From a851a2d646f439f7126c232ba1524c55a8990872 Mon Sep 17 00:00:00 2001 From: Sadeep Madurange Date: Fri, 9 Jan 2026 16:45:56 +0800 Subject: Remove _site from git. --- _site/log/arduino-due/connections.jpeg | Bin 29090 -> 0 bytes _site/log/arduino-due/index.html | 114 ----------------- _site/log/arduino-due/schematic.png | Bin 68688 -> 0 bytes _site/log/arduino-due/source.tar.gz | Bin 1174 -> 0 bytes _site/log/arduino-uno/3v3.Makefile | 46 ------- _site/log/arduino-uno/Makefile | 43 ------- _site/log/arduino-uno/breadboard.jpeg | Bin 54319 -> 0 bytes _site/log/arduino-uno/index.html | 108 ---------------- _site/log/arduino-uno/pinout.png | Bin 247197 -> 0 bytes _site/log/bumblebee/bee.mp4 | Bin 2352029 -> 0 bytes _site/log/bumblebee/index.html | 85 ------------- _site/log/bumblebee/poster.png | Bin 18024 -> 0 bytes _site/log/bumblebee/thumb_sm.png | Bin 6189 -> 0 bytes _site/log/e-reader/circuit.svg | 145 --------------------- _site/log/e-reader/ereader.mp4 | Bin 3101166 -> 0 bytes _site/log/e-reader/index.html | 117 ----------------- _site/log/e-reader/poster.png | Bin 674187 -> 0 bytes _site/log/e-reader/source.tar.gz | Bin 14304 -> 0 bytes _site/log/e-reader/thumb_sm.png | Bin 240117 -> 0 bytes _site/log/etlas/circuit.svg | 105 --------------- _site/log/etlas/dash.jpg | Bin 85874 -> 0 bytes _site/log/etlas/etlas_arch.png | Bin 47732 -> 0 bytes _site/log/etlas/index.html | 153 ---------------------- _site/log/etlas/pcb.jpg | Bin 75769 -> 0 bytes _site/log/etlas/schematic.svg | 4 - _site/log/etlas/source.tar.gz | Bin 46871 -> 0 bytes _site/log/etlas/thumb_sm.jpg | Bin 55678 -> 0 bytes _site/log/fpm-door-lock-lp/breadboard.jpg | Bin 46771 -> 0 bytes _site/log/fpm-door-lock-lp/footprint.png | Bin 198127 -> 0 bytes _site/log/fpm-door-lock-lp/gerber.zip | Bin 89431 -> 0 bytes _site/log/fpm-door-lock-lp/index.html | 110 ---------------- _site/log/fpm-door-lock-lp/pcb.jpg | Bin 68237 -> 0 bytes _site/log/fpm-door-lock-lp/pcb1.jpg | Bin 37068 -> 0 bytes _site/log/fpm-door-lock-lp/source.tar.gz | Bin 29473 -> 0 bytes _site/log/fpm-door-lock-lp/thumb_sm.jpg | Bin 18380 -> 0 bytes _site/log/fpm-door-lock-lp/video.mp4 | Bin 13264594 -> 0 bytes _site/log/fpm-door-lock-rf/back.jpeg | Bin 34023 -> 0 bytes _site/log/fpm-door-lock-rf/back_design.jpeg | Bin 31946 -> 0 bytes _site/log/fpm-door-lock-rf/front.jpeg | Bin 28997 -> 0 bytes _site/log/fpm-door-lock-rf/front_design.jpeg | Bin 32174 -> 0 bytes _site/log/fpm-door-lock-rf/gerber_back.zip | Bin 48217 -> 0 bytes _site/log/fpm-door-lock-rf/gerber_front.zip | Bin 49605 -> 0 bytes _site/log/fpm-door-lock-rf/index.html | 125 ------------------ _site/log/fpm-door-lock-rf/source.tar.gz | Bin 6660 -> 0 bytes _site/log/fpm-door-lock-rf/thumb_sm.jpeg | Bin 6181 -> 0 bytes _site/log/matrix-digital-rain/index.html | 110 ---------------- _site/log/matrix-digital-rain/matrix.mp4 | Bin 696574 -> 0 bytes _site/log/matrix-digital-rain/poster.png | Bin 233077 -> 0 bytes _site/log/matrix-digital-rain/thumb_sm.png | Bin 52762 -> 0 bytes _site/log/mosfet-switches/bjt.png | Bin 12838 -> 0 bytes _site/log/mosfet-switches/index.html | 141 -------------------- _site/log/mosfet-switches/n_high_side.png | Bin 10825 -> 0 bytes _site/log/mosfet-switches/p_high_side.png | Bin 10724 -> 0 bytes _site/log/neo4j-a-star-search/index.html | 106 --------------- _site/log/site-search/index.html | 184 --------------------------- 55 files changed, 1696 deletions(-) delete mode 100644 _site/log/arduino-due/connections.jpeg delete mode 100644 _site/log/arduino-due/index.html delete mode 100644 _site/log/arduino-due/schematic.png delete mode 100644 _site/log/arduino-due/source.tar.gz delete mode 100644 _site/log/arduino-uno/3v3.Makefile delete mode 100644 _site/log/arduino-uno/Makefile delete mode 100644 _site/log/arduino-uno/breadboard.jpeg delete mode 100644 _site/log/arduino-uno/index.html delete mode 100644 _site/log/arduino-uno/pinout.png delete mode 100644 _site/log/bumblebee/bee.mp4 delete mode 100644 _site/log/bumblebee/index.html delete mode 100644 _site/log/bumblebee/poster.png delete mode 100644 _site/log/bumblebee/thumb_sm.png delete mode 100644 _site/log/e-reader/circuit.svg delete mode 100644 _site/log/e-reader/ereader.mp4 delete mode 100644 _site/log/e-reader/index.html delete mode 100644 _site/log/e-reader/poster.png delete mode 100644 _site/log/e-reader/source.tar.gz delete mode 100644 _site/log/e-reader/thumb_sm.png delete mode 100644 _site/log/etlas/circuit.svg delete mode 100644 _site/log/etlas/dash.jpg delete mode 100644 _site/log/etlas/etlas_arch.png delete mode 100644 _site/log/etlas/index.html delete mode 100644 _site/log/etlas/pcb.jpg delete mode 100644 _site/log/etlas/schematic.svg delete mode 100644 _site/log/etlas/source.tar.gz delete mode 100644 _site/log/etlas/thumb_sm.jpg delete mode 100644 _site/log/fpm-door-lock-lp/breadboard.jpg delete mode 100644 _site/log/fpm-door-lock-lp/footprint.png delete mode 100644 _site/log/fpm-door-lock-lp/gerber.zip delete mode 100644 _site/log/fpm-door-lock-lp/index.html delete mode 100644 _site/log/fpm-door-lock-lp/pcb.jpg delete mode 100644 _site/log/fpm-door-lock-lp/pcb1.jpg delete mode 100644 _site/log/fpm-door-lock-lp/source.tar.gz delete mode 100644 _site/log/fpm-door-lock-lp/thumb_sm.jpg delete mode 100644 _site/log/fpm-door-lock-lp/video.mp4 delete mode 100644 _site/log/fpm-door-lock-rf/back.jpeg delete mode 100644 _site/log/fpm-door-lock-rf/back_design.jpeg delete mode 100644 _site/log/fpm-door-lock-rf/front.jpeg delete mode 100644 _site/log/fpm-door-lock-rf/front_design.jpeg delete mode 100644 _site/log/fpm-door-lock-rf/gerber_back.zip delete mode 100644 _site/log/fpm-door-lock-rf/gerber_front.zip delete mode 100644 _site/log/fpm-door-lock-rf/index.html delete mode 100644 _site/log/fpm-door-lock-rf/source.tar.gz delete mode 100644 _site/log/fpm-door-lock-rf/thumb_sm.jpeg delete mode 100644 _site/log/matrix-digital-rain/index.html delete mode 100644 _site/log/matrix-digital-rain/matrix.mp4 delete mode 100644 _site/log/matrix-digital-rain/poster.png delete mode 100644 _site/log/matrix-digital-rain/thumb_sm.png delete mode 100644 _site/log/mosfet-switches/bjt.png delete mode 100644 _site/log/mosfet-switches/index.html delete mode 100644 _site/log/mosfet-switches/n_high_side.png delete mode 100644 _site/log/mosfet-switches/p_high_side.png delete mode 100644 _site/log/neo4j-a-star-search/index.html delete mode 100644 _site/log/site-search/index.html (limited to '_site/log') diff --git a/_site/log/arduino-due/connections.jpeg b/_site/log/arduino-due/connections.jpeg deleted file mode 100644 index 081e6d4..0000000 Binary files a/_site/log/arduino-due/connections.jpeg and /dev/null differ diff --git a/_site/log/arduino-due/index.html b/_site/log/arduino-due/index.html deleted file mode 100644 index ed49e78..0000000 --- a/_site/log/arduino-due/index.html +++ /dev/null @@ -1,114 +0,0 @@ - - - - - - ATSAM3X8E bare-metal notes - - - - - - - - - - - -
-
-
-

ATSAM3X8E BARE-METAL NOTES

-
16 SEPTEMBER 2024
-
-

Bypassing ATSAM3X8E (Due) bootloader via Serial Wire Debug (SWD).

- -

Toolchain: ST-LINK/V2 programmer, OpenOCD, ARM GNU Compiler Toolchain.

- -

ARM chips boot into 0x00000. GPNVM bits map one of ROM, flash0, flash1 to -0x00000:

- -
    -
  • GPNVM1=0 → ROM (default).
  • -
  • GPNVM1=1 and GPNVM2=0 → flash0.
  • -
  • GPNVM1=1 and GPNVM2=1 → flash1.
  • -
- -

By default, control jumps to Atmel’s SAM-BA bootloader in ROM. To bypass, set -GPNVM1=1 and place vector table at 0x80000 (flash0).

- -

Connect ST-LINK/v2 to Arduino Due’s DEBUG port:

- - - - - - -
- Pinout -

Wiring

-
- Circuit -

Arduino Due

-
- -

Remap memory:

- -
$ openocd -f openocd-due.cfg
-$ telnet localhost 4444
-  > halt
-  > at91sam3 gpnvm show
-  > at91sam3 gpnvm set 1
-  > at91sam3 gpnvm show
-
- -

Full command list is in OpenOCD manual AT91SAM3 (flash driver section).

- -

Compile and upload program:

- -
$ arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -T script.ld \
-    -nostartfiles \
-    -nostdlib \
-    -o a.elf main.c
-$ openocd -f openocd-due.cfg -c "program a.elf verify reset exit"
-
- -

Commit: -3184969

- -
- -
-
-
- - - - - - diff --git a/_site/log/arduino-due/schematic.png b/_site/log/arduino-due/schematic.png deleted file mode 100644 index 62ddadd..0000000 Binary files a/_site/log/arduino-due/schematic.png and /dev/null differ diff --git a/_site/log/arduino-due/source.tar.gz b/_site/log/arduino-due/source.tar.gz deleted file mode 100644 index 496567b..0000000 Binary files a/_site/log/arduino-due/source.tar.gz and /dev/null differ diff --git a/_site/log/arduino-uno/3v3.Makefile b/_site/log/arduino-uno/3v3.Makefile deleted file mode 100644 index 4ca89d4..0000000 --- a/_site/log/arduino-uno/3v3.Makefile +++ /dev/null @@ -1,46 +0,0 @@ -CC = avr-gcc -MCU = atmega328p -PORT = /dev/cuaU0 -TARGET = app - -SRC = main.c -OBJ = $(SRC:.c=.o) - -CFLAGS = -std=gnu99 -CFLAGS += -Os -CFLAGS += -Wall -CFLAGS += -mmcu=$(MCU) -CFLAGS += -DBAUD=57600 -CFLAGS += -DF_CPU=8000000UL -CFLAGS += -ffunction-sections -fdata-sections - -LDFLAGS = -mmcu=$(MCU) -LDFLAGS += -Wl,--gc-sections - -HEX_FLAGS = -O ihex -HEX_FLAGS += -j .text -j .data - -AVRDUDE_FLAGS = -p $(MCU) -AVRDUDE_FLAGS += -c arduino -AVRDUDE_FLAGS += -b 57600 -AVRDUDE_FLAGS += -P $(PORT) -AVRDUDE_FLAGS += -D -U - -%.o: %.c - $(CC) $(CFLAGS) -c -o $@ $< - -elf: $(OBJ) - $(CC) $(LDFLAGS) $(OBJ) -o $(TARGET).elf - -hex: elf - avr-objcopy $(HEX_FLAGS) $(TARGET).elf $(TARGET).hex - -upload: hex - avrdude $(AVRDUDE_FLAGS) flash:w:$(TARGET).hex:i - -.PHONY: clean - -clean: - rm -f *.o *.elf *.hex - - diff --git a/_site/log/arduino-uno/Makefile b/_site/log/arduino-uno/Makefile deleted file mode 100644 index 9db7b09..0000000 --- a/_site/log/arduino-uno/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -CC = avr-gcc -MCU = atmega328p -PORT = /dev/cuaU0 -TARGET = app - -SRC = main.c -OBJ = $(SRC:.c=.o) - -CFLAGS = -std=gnu99 -CFLAGS += -Os -CFLAGS += -Wall -CFLAGS += -mmcu=$(MCU) -CFLAGS += -DBAUD=115200 -CFLAGS += -DF_CPU=16000000UL -CFLAGS += -ffunction-sections -fdata-sections - -LDFLAGS = -mmcu=$(MCU) -LDFLAGS += -Wl,--gc-sections - -HEX_FLAGS = -O ihex -HEX_FLAGS += -j .text -j .data - -AVRDUDE_FLAGS = -p $(MCU) -AVRDUDE_FLAGS += -c arduino -AVRDUDE_FLAGS += -P $(PORT) -AVRDUDE_FLAGS += -D -U - -%.o: %.c - $(CC) $(CFLAGS) -c -o $@ $< - -elf: $(OBJ) - $(CC) $(LDFLAGS) $(OBJ) -o $(TARGET).elf - -hex: elf - avr-objcopy $(HEX_FLAGS) $(TARGET).elf $(TARGET).hex - -upload: hex - avrdude $(AVRDUDE_FLAGS) flash:w:$(TARGET).hex:i - -.PHONY: clean - -clean: - rm *.o *.elf *.hex diff --git a/_site/log/arduino-uno/breadboard.jpeg b/_site/log/arduino-uno/breadboard.jpeg deleted file mode 100644 index bd74907..0000000 Binary files a/_site/log/arduino-uno/breadboard.jpeg and /dev/null differ diff --git a/_site/log/arduino-uno/index.html b/_site/log/arduino-uno/index.html deleted file mode 100644 index 3eee3a3..0000000 --- a/_site/log/arduino-uno/index.html +++ /dev/null @@ -1,108 +0,0 @@ - - - - - - ATmega328P at 3.3V and 5V - - - - - - - - - - - -
-
-
-

ATMEGA328P AT 3.3V AND 5V

-
10 JUNE 2025
-
-

Quick reference for wiring ATmega328P ICs at 5V and 3.3V. 5V uses 16MHz -crystal, 3.3V uses 8MHz.

- - - - - - -
- Pinout -

Pinout

-
- Circuit -

Breadboard

-
- -

5V-16MHz

- -

Standard setup. How Arduino Uno boards are wired.

- -

Connections: Pin 1 → 5V via 10kΩ resistor. Pins 9/10 → 16MHz crystal via 22pF -capacitors to ground. Pins 7/20/21 → 5V supply. Pins 8/22 → ground. Add 0.1μF -decoupling caps between pins 7/20/21 and ground.

- -

Sample Makefile: Makefile

- -

3.3V-8MHz

- -

Electrical connections identical to 5V circuit. Replace 5V with 3.3V supply, -16MHz crystal with 8MHz.

- -

Problem: ATmega328P ships configured for 5V. Must modify fuses (BOD level, -etc.) and replace bootloader. Standard Arduino bootloader expects 16MHz—needs -8MHz version.

- -

Solution: Use Arduino Uno as ISP. Upload ‘ArduinoISP’ sketch from Arduino IDE. -Connect SPI pins (ATmega328P ↔ Uno), Uno’s SS pin → ATmega328P RESET pin. Power -ATmega328P from Uno’s 5V pin during programming.

- -

Arduino IDE: Select ‘ATmega328P (3.3V, 8MHz)’ processor, ‘Arduino as ISP’ -programmer. Burn bootloader via tools menu.

- -

Sample Makefile (8MHz): Makefile.3v3

- -

Remarks

- -

Don’t connect AREF (pin 21) to Vcc if using ADC with internal 1.1V -or AVcc reference. See datasheet section 23.5.2.

- -
- -
-
-
- - - - - - diff --git a/_site/log/arduino-uno/pinout.png b/_site/log/arduino-uno/pinout.png deleted file mode 100644 index 59acfbc..0000000 Binary files a/_site/log/arduino-uno/pinout.png and /dev/null differ diff --git a/_site/log/bumblebee/bee.mp4 b/_site/log/bumblebee/bee.mp4 deleted file mode 100644 index 835600d..0000000 Binary files a/_site/log/bumblebee/bee.mp4 and /dev/null differ diff --git a/_site/log/bumblebee/index.html b/_site/log/bumblebee/index.html deleted file mode 100644 index 984187b..0000000 --- a/_site/log/bumblebee/index.html +++ /dev/null @@ -1,85 +0,0 @@ - - - - - - Bumblebee: web script synthesizer - - - - - - - - - - - -
-
-
-

BUMBLEBEE: WEB SCRIPT SYNTHESIZER

-
02 APRIL 2025
-
-

Browser session-to-code conversion. For work. Pre-LLM.

- - - -

Quality of scripts are pitiful.

- -

Created tool to generate them real-time (as the user browses the web).

- -

Architecture: C# WinForms host, embedded WebView2 browser, Scintilla.NET -editor.

- -

Implementation:

- -
    -
  • Interception: Injected JS hooks + internal browser events.
  • -
  • Transformation: Event → Token → Instruction table → String.
  • -
  • Optimization: Parallel event/text lists.
  • -
  • Two-way binding of code to Scintilla editor.
  • -
- -

NOTE: Abstract syntax trees.

- -

Script generation: minutes/hours → seconds.

- -
- -
-
-
- - - - - - diff --git a/_site/log/bumblebee/poster.png b/_site/log/bumblebee/poster.png deleted file mode 100644 index 6dc955e..0000000 Binary files a/_site/log/bumblebee/poster.png and /dev/null differ diff --git a/_site/log/bumblebee/thumb_sm.png b/_site/log/bumblebee/thumb_sm.png deleted file mode 100644 index f7cfbf3..0000000 Binary files a/_site/log/bumblebee/thumb_sm.png and /dev/null differ diff --git a/_site/log/e-reader/circuit.svg b/_site/log/e-reader/circuit.svg deleted file mode 100644 index fd7508b..0000000 --- a/_site/log/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/log/e-reader/ereader.mp4 b/_site/log/e-reader/ereader.mp4 deleted file mode 100644 index 89e05eb..0000000 Binary files a/_site/log/e-reader/ereader.mp4 and /dev/null differ diff --git a/_site/log/e-reader/index.html b/_site/log/e-reader/index.html deleted file mode 100644 index 13b4efa..0000000 --- a/_site/log/e-reader/index.html +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - 512KB e-reader - - - - - - - - - - - -
-
-
-

512KB E-READER

-
24 OCTOBER 2023
-
-

First project with e-paper.

- - - -

ESP-WROOM-32, 7.5” Waveshare e-paper display, three-button interface -(prev/next/sleep).

- -

Memory: 512KB SRAM + 4MB flash. Internal flash unsuitable for storing books due -to P/E cycle limit. Used HTTP Range requests to stream them on-demand. -Progress saved to RTC memory to survive deep sleep without flash wear.

- -

PDFs are rasterized and stored as sequences of bitmaps on a server. 1 byte = 8 -pixels, 1 page = 48KB (display resolution), headerless. Optimized for Range -requests without server-side logic:

- -
int r0 = ((page_n - 1) * PAGE_SIZE);
-int rn = page_n * PAGE_SIZE - 1;
-
-int n = snprintf(NULL, 0, "bytes=%d-%d", r0, rn) + 1;
-char *buf = malloc(sizeof(char) * n);
-snprintf(buf, n, "bytes=%d-%d", r0, rn);
-
-esp_http_client_set_header(http_client, "Range", buf);
-esp_http_client_perform(http_client);
-
- -

Three pages (prev/current/next) held in a buffer—maximum possible. Upon -request, embedded software cycles the buffer, updates the screen, prefetches -the next page.

- -
c_page_num++;
-pg.page_num = c_page_num + 2;
-pg.page_buf = pages[(c_page_num + 1) % PAGE_LEN];
-
-xSemaphoreGive(mutex);
-xQueueSend(http_evt_queue, &pg, portMAX_DELAY);
-
-epd_draw_async(pages[c_page_num % PAGE_LEN], PAGE_SIZE);
-epd_draw_await();
-
- -

System isn’t as responsive as I’d hoped. Scheduling GPIO, SPI, and HTTP tasks -on a single thread causes input lag. Pinned GPIO/SPI tasks to one core and the -HTTP task to the other.

- -

Better, but screen updates block user input.

- -

Moved the SPI buffers to DMA and made the transfers async. Few more cycles -saved.

- -

Can’t think of anything else.

- -

Verdict: Functional but limited. Led to Etlas.

- -

Commit: -7f691c4

-
- -
-
-
- - - - - - diff --git a/_site/log/e-reader/poster.png b/_site/log/e-reader/poster.png deleted file mode 100644 index 1e222d2..0000000 Binary files a/_site/log/e-reader/poster.png and /dev/null differ diff --git a/_site/log/e-reader/source.tar.gz b/_site/log/e-reader/source.tar.gz deleted file mode 100644 index 3e343a7..0000000 Binary files a/_site/log/e-reader/source.tar.gz and /dev/null differ diff --git a/_site/log/e-reader/thumb_sm.png b/_site/log/e-reader/thumb_sm.png deleted file mode 100644 index 7c971e8..0000000 Binary files a/_site/log/e-reader/thumb_sm.png and /dev/null differ diff --git a/_site/log/etlas/circuit.svg b/_site/log/etlas/circuit.svg deleted file mode 100644 index 6255045..0000000 --- a/_site/log/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/log/etlas/dash.jpg b/_site/log/etlas/dash.jpg deleted file mode 100644 index cf4efc6..0000000 Binary files a/_site/log/etlas/dash.jpg and /dev/null differ diff --git a/_site/log/etlas/etlas_arch.png b/_site/log/etlas/etlas_arch.png deleted file mode 100644 index 241e9f1..0000000 Binary files a/_site/log/etlas/etlas_arch.png and /dev/null differ diff --git a/_site/log/etlas/index.html b/_site/log/etlas/index.html deleted file mode 100644 index 68c19ae..0000000 --- a/_site/log/etlas/index.html +++ /dev/null @@ -1,153 +0,0 @@ - - - - - - Etlas: e-paper dashboard - - - - - - - - - - - -
-
-
-

ETLAS: E-PAPER DASHBOARD

-
05 SEPTEMBER 2024
-
-

Repurposed the e-reader into something for regular use. News, -stocks, weather dashboard. ESP32 NodeMCU D1 + 7.5” Waveshare e-paper + DHT22 -sensor.

- - - - - - - - - -
frontback
front
- -

Stocks: Two weeks EOD data from Polygon.io (max possible). Flask app on VPS -manages watchlist, relays the feed. Backend: httpd + htpasswd + slowcgi + -Flask.

- -

gui_plot_stocks() plots a stepped graph; was easier to implement, but the code -is hideous; triggers watchdog. vTaskDelay() prevents that.

- -

NOTE: Refactor. Bresenham’s?

- -

News: Channel NewsAsia RSS. MCU does the parsing. Didn’t plan to have a backend -at the time. Now that I have one for stocks, should relay the feed for -flexibility.

- -

Weather: DHT22 single-wire protocol. 26µs/50µs/70µs pulses are too fast for -standard ESP32 APIs. Bit-banged relative pulse widths (ported from ESP8266):

- -
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[BUFLEN])
-{
-    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 < BUFLEN; 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;
-}
-
- -

epd_init() stalls intermittently on first refresh() after flash. Toggling delay -values in refresh() resolves it. If the first refresh succeeds, it remains -stable. Root cause unknown–suspect noisy power supply due to powering display -via MCU.

- -

Uptime: August 2024 - January 2026

- -

Commit: -a92c86a

-
- -
-
-
- - - - - - diff --git a/_site/log/etlas/pcb.jpg b/_site/log/etlas/pcb.jpg deleted file mode 100644 index fcb40fa..0000000 Binary files a/_site/log/etlas/pcb.jpg and /dev/null differ diff --git a/_site/log/etlas/schematic.svg b/_site/log/etlas/schematic.svg deleted file mode 100644 index 3070dd1..0000000 --- a/_site/log/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/log/etlas/source.tar.gz b/_site/log/etlas/source.tar.gz deleted file mode 100644 index 8b12cf6..0000000 Binary files a/_site/log/etlas/source.tar.gz and /dev/null differ diff --git a/_site/log/etlas/thumb_sm.jpg b/_site/log/etlas/thumb_sm.jpg deleted file mode 100644 index a374879..0000000 Binary files a/_site/log/etlas/thumb_sm.jpg and /dev/null differ diff --git a/_site/log/fpm-door-lock-lp/breadboard.jpg b/_site/log/fpm-door-lock-lp/breadboard.jpg deleted file mode 100644 index 2bf47a9..0000000 Binary files a/_site/log/fpm-door-lock-lp/breadboard.jpg and /dev/null differ diff --git a/_site/log/fpm-door-lock-lp/footprint.png b/_site/log/fpm-door-lock-lp/footprint.png deleted file mode 100644 index 5511bf1..0000000 Binary files a/_site/log/fpm-door-lock-lp/footprint.png and /dev/null differ diff --git a/_site/log/fpm-door-lock-lp/gerber.zip b/_site/log/fpm-door-lock-lp/gerber.zip deleted file mode 100644 index 19a9d19..0000000 Binary files a/_site/log/fpm-door-lock-lp/gerber.zip and /dev/null differ diff --git a/_site/log/fpm-door-lock-lp/index.html b/_site/log/fpm-door-lock-lp/index.html deleted file mode 100644 index a39a34e..0000000 --- a/_site/log/fpm-door-lock-lp/index.html +++ /dev/null @@ -1,110 +0,0 @@ - - - - - - Fingerprint door lock (LP) - - - - - - - - - - - -
-
-
-

FINGERPRINT DOOR LOCK (LP)

-
18 AUGUST 2025
-
-

Second iteration of the RF door lock. 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.

- - - -

Redesigned the PCB completely. Tossed RF modules and the second MCU. Connected -R503 directly to the ATmega328P. Sensor now mounts on door exterior, servo -attaches to interior knob, MCU stays on the back to prevent tampering.

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

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 RFM–noise -isn’t a big concern. Buck’s pin breakout not great–wouldn’t fit commercial dev -boards.

- -

Squeezed more power savings by underclocking MCU to 8MHz/3.3V. Combined -with buck converters: 56% total power savings.

- -

Wake sequence: MCU activates FPM MOSFET, unlocks FPM 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 -| Gerber: gerber.zip

-
- -
-
-
- - - - - - diff --git a/_site/log/fpm-door-lock-lp/pcb.jpg b/_site/log/fpm-door-lock-lp/pcb.jpg deleted file mode 100644 index fbd800b..0000000 Binary files a/_site/log/fpm-door-lock-lp/pcb.jpg and /dev/null differ diff --git a/_site/log/fpm-door-lock-lp/pcb1.jpg b/_site/log/fpm-door-lock-lp/pcb1.jpg deleted file mode 100644 index 367187d..0000000 Binary files a/_site/log/fpm-door-lock-lp/pcb1.jpg and /dev/null differ diff --git a/_site/log/fpm-door-lock-lp/source.tar.gz b/_site/log/fpm-door-lock-lp/source.tar.gz deleted file mode 100644 index ef23422..0000000 Binary files a/_site/log/fpm-door-lock-lp/source.tar.gz and /dev/null differ diff --git a/_site/log/fpm-door-lock-lp/thumb_sm.jpg b/_site/log/fpm-door-lock-lp/thumb_sm.jpg deleted file mode 100644 index a8fa534..0000000 Binary files a/_site/log/fpm-door-lock-lp/thumb_sm.jpg and /dev/null differ diff --git a/_site/log/fpm-door-lock-lp/video.mp4 b/_site/log/fpm-door-lock-lp/video.mp4 deleted file mode 100644 index a907a9b..0000000 Binary files a/_site/log/fpm-door-lock-lp/video.mp4 and /dev/null differ diff --git a/_site/log/fpm-door-lock-rf/back.jpeg b/_site/log/fpm-door-lock-rf/back.jpeg deleted file mode 100644 index f458e69..0000000 Binary files a/_site/log/fpm-door-lock-rf/back.jpeg and /dev/null differ diff --git a/_site/log/fpm-door-lock-rf/back_design.jpeg b/_site/log/fpm-door-lock-rf/back_design.jpeg deleted file mode 100644 index b6c0f5d..0000000 Binary files a/_site/log/fpm-door-lock-rf/back_design.jpeg and /dev/null differ diff --git a/_site/log/fpm-door-lock-rf/front.jpeg b/_site/log/fpm-door-lock-rf/front.jpeg deleted file mode 100644 index 2b2931f..0000000 Binary files a/_site/log/fpm-door-lock-rf/front.jpeg and /dev/null differ diff --git a/_site/log/fpm-door-lock-rf/front_design.jpeg b/_site/log/fpm-door-lock-rf/front_design.jpeg deleted file mode 100644 index f81f09c..0000000 Binary files a/_site/log/fpm-door-lock-rf/front_design.jpeg and /dev/null differ diff --git a/_site/log/fpm-door-lock-rf/gerber_back.zip b/_site/log/fpm-door-lock-rf/gerber_back.zip deleted file mode 100644 index 26659ad..0000000 Binary files a/_site/log/fpm-door-lock-rf/gerber_back.zip and /dev/null differ diff --git a/_site/log/fpm-door-lock-rf/gerber_front.zip b/_site/log/fpm-door-lock-rf/gerber_front.zip deleted file mode 100644 index 864334e..0000000 Binary files a/_site/log/fpm-door-lock-rf/gerber_front.zip and /dev/null differ diff --git a/_site/log/fpm-door-lock-rf/index.html b/_site/log/fpm-door-lock-rf/index.html deleted file mode 100644 index 55675ff..0000000 --- a/_site/log/fpm-door-lock-rf/index.html +++ /dev/null @@ -1,125 +0,0 @@ - - - - - - Fingerprint door lock (RF) - - - - - - - - - - - -
-
-
-

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.

- -

Datasheet riddled with ambiguity.

- -

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 driver from scratch–clean-room. -Works like a charm.

- -

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 PCB boards for FPM (front) and servo (back) controllers. Encrypted -RF link between them.

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

Footprint (front)

-
- PCB (front) -

PCB (front)

-
- Design (back) -

Footprint (back)

-
- PCB (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

-
- -
-
-
- - - - - - diff --git a/_site/log/fpm-door-lock-rf/source.tar.gz b/_site/log/fpm-door-lock-rf/source.tar.gz deleted file mode 100644 index c31aa22..0000000 Binary files a/_site/log/fpm-door-lock-rf/source.tar.gz and /dev/null differ diff --git a/_site/log/fpm-door-lock-rf/thumb_sm.jpeg b/_site/log/fpm-door-lock-rf/thumb_sm.jpeg deleted file mode 100644 index c275b12..0000000 Binary files a/_site/log/fpm-door-lock-rf/thumb_sm.jpeg and /dev/null differ diff --git a/_site/log/matrix-digital-rain/index.html b/_site/log/matrix-digital-rain/index.html deleted file mode 100644 index 1915d04..0000000 --- a/_site/log/matrix-digital-rain/index.html +++ /dev/null @@ -1,110 +0,0 @@ - - - - - - Matrix Rain: 2025 refactor - - - - - - - - - - - -
-
-
-

MATRIX RAIN: 2025 REFACTOR

-
21 DECEMBER 2025
-
-

The 2022 version worked but had some loose ends. Unicode support was -inflexible–couldn’t mix ASCII with Katakana; Phosphor decay was stored in a -separate array when it should’ve been packed with RGB; Code was harder to read -than it needed to be.

- - - -

Moved phosphor decay into the 4th byte of the RGB union–should’ve done this -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. -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 */
-};
-
-static inline void insert_code(matrix *mat,
-    size_t row, size_t col) 
-{
-    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;
-}
-
- -

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.

- -

Commit: f71b0de.

- -
- -
-
-
- - - - - - diff --git a/_site/log/matrix-digital-rain/matrix.mp4 b/_site/log/matrix-digital-rain/matrix.mp4 deleted file mode 100644 index 7edf5d6..0000000 Binary files a/_site/log/matrix-digital-rain/matrix.mp4 and /dev/null differ diff --git a/_site/log/matrix-digital-rain/poster.png b/_site/log/matrix-digital-rain/poster.png deleted file mode 100644 index 1f68ca4..0000000 Binary files a/_site/log/matrix-digital-rain/poster.png and /dev/null differ diff --git a/_site/log/matrix-digital-rain/thumb_sm.png b/_site/log/matrix-digital-rain/thumb_sm.png deleted file mode 100644 index 940965a..0000000 Binary files a/_site/log/matrix-digital-rain/thumb_sm.png and /dev/null differ diff --git a/_site/log/mosfet-switches/bjt.png b/_site/log/mosfet-switches/bjt.png deleted file mode 100644 index 9858fa7..0000000 Binary files a/_site/log/mosfet-switches/bjt.png and /dev/null differ diff --git a/_site/log/mosfet-switches/index.html b/_site/log/mosfet-switches/index.html deleted file mode 100644 index a91f205..0000000 --- a/_site/log/mosfet-switches/index.html +++ /dev/null @@ -1,141 +0,0 @@ - - - - - - High-side MOSFET switching - - - - - - - - - - - -
-
-
-

HIGH-SIDE MOSFET SWITCHING

-
22 JUNE 2025
-
-

Needed low-power switching for the fingerprint door -lock. Servo and FPM draw high quiescent current–had to -cut power electronically during sleep. MOSFETs can do this.

- -

Schematics belong to Simon Fitch.

- -

Problem with simple low-side switching

- -

Typical approach: GPIO → gate of N-channel MOSFET on low side, pull-down -resistor between gate and drain. Works if MCU and load don’t share common -ground. Doesn’t work when they do (like controlling a component powered by the -same MCU).

- -

Issue: source potential = gate potential - threshold voltage. Example: 3.3V -gate - 1.5V threshold → 1.8V at load–not nearly enough for a servo. Raising -the gate potential above source is not always practical. Solution: high-side -switch.

- -

P-channel high-side switch

- -

P-channel high-side switching circuit

- -

M1 is P-channel (high-side), M2 is N-channel (level converter). MCU output low -→ M2 off → R1 pulls M1 gate to +6V → servo off. MCU output high → M2 conducts → -M1 gate drops to 0V → servo on.

- -

Note: IRF9540 in the schematic doesn’t work. VGS (-10V) for -RDSon too much for 3.3V ATmega328P to drive. NDP6020P is the only -suitable through-hole MOSFET I could find.

- -

N-channel high-side switch

- -

N-channel high-side switching circuit

- -

Less common but works if you have voltage high enough to drive the gate. Both -M1 and M2 are N-channel. MCU low → M2 off → M1 gate rises above threshold → -servo on. MCU high → M2 on → M1 gate drops → servo off. R2 prevents -high-impedance power-up from switching servo on.

- -

M2 needed in both topologies for level conversion (0V ↔ +6V or +9V). Carries -<1mA. Gate-source threshold must be lower than MCU supply. Common choices: -2N7000, 2N7002, BSS138.

- -

Note: D1 flyback diodes protect MOSFETs from voltage spikes caused by inductive -loads (servos, relays).

- -

A BJT alternative

- -

BJT architecture

- -

Simpler, cheaper, more available. Q2 conducts when MCU outputs high. Q2 -amplifies Q1’s base current. Unlike MOSFETs (voltage-driven), BJTs are -current-driven. R3 and R4 must be calculated for desired base currents. Guide on BJT -switches.

- -

Which topology?

- -

MOSFETs preferred in professional work—more efficient when on. Harder to drive -at 3.3V due to VGS requirements for full saturation (low -RDS(on)).

- -

N-channel: Lower on-resistance, cheaper, more efficient than P-channel. Harder -to drive high-side (gate must be above source—requires extra circuitry like -MOSFET drivers).

- -

Used P-channel high-side for the door lock redesign. Simpler to drive from 3.3V -MCU, no driver needed.

- -

Further reading

- - -
- -
-
-
- - - - - - diff --git a/_site/log/mosfet-switches/n_high_side.png b/_site/log/mosfet-switches/n_high_side.png deleted file mode 100644 index c851768..0000000 Binary files a/_site/log/mosfet-switches/n_high_side.png and /dev/null differ diff --git a/_site/log/mosfet-switches/p_high_side.png b/_site/log/mosfet-switches/p_high_side.png deleted file mode 100644 index 9f5397a..0000000 Binary files a/_site/log/mosfet-switches/p_high_side.png and /dev/null differ diff --git a/_site/log/neo4j-a-star-search/index.html b/_site/log/neo4j-a-star-search/index.html deleted file mode 100644 index 2063d68..0000000 --- a/_site/log/neo4j-a-star-search/index.html +++ /dev/null @@ -1,106 +0,0 @@ - - - - - - Neo4J path traversal: A* optimization - - - - - - - - - - - -
-
-
-

NEO4J PATH TRAVERSAL: A* OPTIMIZATION

-
06 MARCH 2018
-
-

Work. Vessel tracking with Neo4J hit a limit. Need to analyze 13,000 route -points; Dijkstra’s shortest path search slows after 4,000.

- -

Replaced Dijkstra’s algorithm with A* search using haversine function as -heuristic:

- -
private double computeHeuristic(
-    final double lat1, final double lon1,
-    final double lat2, final double lon2) {
-    final int earthRadius = 6371;
-    final double kmToNM = 0.539957;
-
-    final double latDistance = Math.toRadians(lat2 - lat1);
-    final double lonDistance = Math.toRadians(lon2 - lon1);
-
-    final double a = Math.sin(latDistance / 2) 
-        * Math.sin(latDistance / 2)
-        + Math.cos(Math.toRadians(lat1)) 
-        * Math.cos(Math.toRadians(lat2))
-        * Math.sin(lonDistance / 2) 
-        * Math.sin(lonDistance / 2);
-
-    final double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
-
-    return earthRadius * c * kmToNM;
-}
-
- -

Core search loop updates costs when better path found:

- -
private void updateCosts(
-    final int source, final int target,
-    final double newCost, final double heuristic) {
-    final double oldCost = gCosts.getOrDefault(target, Double.MAX_VALUE);
-    if (newCost < oldCost) {
-        gCosts.put(target, newCost);
-        fCosts.put(target, newCost + heuristic);
-        path.put(target, source);
-    }
-}
-
- -

300x speedup. Scaled to 13,000 route points.

- -

Upstreamed changes: Neo4J v3.4.0 | -Full -source

-
- -
-
-
- - - - - - diff --git a/_site/log/site-search/index.html b/_site/log/site-search/index.html deleted file mode 100644 index 77fe19e..0000000 --- a/_site/log/site-search/index.html +++ /dev/null @@ -1,184 +0,0 @@ - - - - - - Full-text search: SA lookup - - - - - - - - - - - -
-
-
-

FULL-TEXT SEARCH: SA LOOKUP

-
03 JANUARY 2026
-
-

Article count is growing. Need a way to search.

- -

Requirements: matches substrings, case-insensitive, fast, secure. No -JavaScript.

- -

Architecture: browser → httpd → slowcgi → Perl CGI script.

- -

Perl, httpd, slowcgi are in the OpenBSD base system. Instead of secrets, file -system permissions govern access.

- -

2025-12-30: Regex search.

- -

140-line Perl script searches 500 files in 40ms. Fast enough; O(N) pull felt at -higher file counts.

- -

Introduces ReDoS and symlink attack vectors. Both can be mitigated. Tempted to -stop here.

- -

2026-01-03: Suffix Array (SA) based index lookup.

- -

Slurping files on every request bothers me. Regex search depends almost -entirely on hardware for speed.

- -

Implemented SA index with three files: corpus.bin, sa.bin, file_map.dat. Index -built with site:

- -
$ JEKYLL_ENV=production bundle exec jekyll build
-$ cd cgi-bin/
-$ perl indexer.pl
-
- -

Indexer extracts HTML, lowercases, encodes into UTF-8 binary sequences. Null -byte sentinel for document boundaries. sa.bin stores suffix offsets as -32-bit unsigned integers, sorted by lexicographical order:

- -
my @sa = 0 .. (length($corpus) - 1);
-{
-    use bytes; # Force compare 8-bit Unicode value comparisons
-    @sa = sort { 
-        # First 64 bytes check (fast path)
-        (substr($corpus, $a, 64) cmp substr($corpus, $b, 64)) || 
-        # Full string fallback (required for correctness)
-        (substr($corpus, $a) cmp substr($corpus, $b))
-    } @sa;
-}
-
-CORPUS:   a  s  c  i \0  i  m  x
-OFFSET:   0  1  2  3  4  5  6  7
-
-SORTED SUFFIXES:
-
-[4] \0imx
-[0] asci\0imx
-[2] ci\0imx
-[3] i\0imx       <-- "i" from "asci"
-[5] imx          <-- "i" from "imx"
-[6] mx
-[1] sci\0imx
-[7] x
-
- -

Time complexity: O(L⋅N log N). Fast path caps L at 64 bytes (length of cache -line), reducing complexity to O(N log N).

- -

Search: Textbook range query with twin binary searches. Random access to -suffixes and the text made possible by the fixed-width offsets:

- -
seek($fh_sa, $mid * 4, 0);
-read($fh_sa, my $bin_off, 4);
-my $off = unpack("L", $bin_off);
-seek($fh_cp, $off, 0);
-read($fh_cp, my $text, $query_len);
-
- -

Small seek/reads are fast on modern SSDs. Keeps memory usage low.

- -

NOTE: mmap.

- -

Benchmarks on T490 (i7-10510U, OpenBSD 7.8, article size: 16 KB).

- -

500 files:

-
    -
  • Index size: 204.94 KB
  • -
  • Indexing time: 0.1475 s
  • -
  • Peak RAM (SA): 8828 KB
  • -
  • Peak RAM (Regex): 9136 KB
  • -
  • Search (SA): 0.0012 s
  • -
  • Search (Regex): 0.0407 s
  • -
- -

1,000 files:

-
    -
  • Index size: 410.51 KB
  • -
  • Indexing time: 0.3101 s
  • -
  • Peak RAM (SA): 8980 KB
  • -
  • Peak RAM (Regex): 9460 KB
  • -
  • Search (SA): 0.0019 s
  • -
  • Search (Regex): 0.0795 s
  • -
- -

10,000 files:

-
    -
  • Index size: 4163.44 KB
  • -
  • Indexing time: 10.9661 s
  • -
  • Peak RAM (SA): 12504 KB
  • -
  • Peak RAM (Regex): 12804 KB
  • -
  • Search (SA): 0.0161 s
  • -
  • Search (Regex): 0.9120 s
  • -
- -

Security: Derived from architectural simplicity. Zero dependencies to manage, -no secrets to hide, no targets for lateral movement.

- -

Runs in chroot.

- -

Resource exhaustion and XSS attacks are inherent. Former mitigated by limiting -concurrent searches via lock-file semaphores. Query length (64B) and result set -(20) capped. All output is HTML-escaped to prevent XSS.

- -

Secure by default. Fast. Durable.

- -

Commit: -6da102d -| Benchmarks: -8a4da68

-
- -
-
-
- - - - - - -- cgit v1.2.3