summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--_log/e-reader.md77
-rw-r--r--_site/feed.xml2
-rw-r--r--_site/index.html2
-rw-r--r--_site/log/e-reader/index.html72
-rw-r--r--_site/posts.xml2
-rw-r--r--_site/projects/index.html4
-rw-r--r--_site/robots.txt2
-rw-r--r--_site/sitemap.xml28
8 files changed, 85 insertions, 104 deletions
diff --git a/_log/e-reader.md b/_log/e-reader.md
index fbc7b94..87417f7 100644
--- a/_log/e-reader.md
+++ b/_log/e-reader.md
@@ -1,5 +1,5 @@
---
-title: ESP32 e-reader prototype
+title: ESP32 prototype e-reader
date: 2023-10-24
layout: post
project: true
@@ -12,62 +12,53 @@ First project with e-paper displays and ESP32.
<source src="ereader.mp4" type="video/mp4">
</video>
-System: ESP-WROOM-32, 7.5" Waveshare e-paper display, three buttons
+ESP-WROOM-32, 7.5" Waveshare e-paper display, three-button interface
(prev/next/sleep).
-2023-09-23: 512KB SRAM, 4MB flash (shared with FreeRTOS and ESP-IDF). Not
-enough storage for books. Using ESP32's built-in WiFi to stream them over HTTP.
-Recording the reading progress in RTC memory.
+Memory: 512KB SRAM + 4MB flash--insufficient for local library. Streams via
+HTTP Range requests over WiFi. Reading progress saved to RTC memory; persists
+through deep sleep.
-Rasterized pages encoded as tightly packed bitmaps (1 byte => 8 pixels), no
-headers, arranged along 48 KB (480x800) boundaries; Reader can stream pages
-using HTTP Range requests with zero server-side logic. Keeps both ends lean.
+EBM format: Raw bitmap sequence. 1 byte = 8 pixels, 1 page = 48 KB (display
+resolution), headerless. Optimized for HTTP Range requests:
-Page table stores 3 pages (prev/current/next) in a circular buffer. When the
-user requests a page, program cycles through the table, updates the screen, and
-downloads the next page.
+```
+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);
-Responsiveness is inadequate. Scheduling GPIO (user input), SPI, and HTTP on
-one core causes input lag. Pinned the GPIO and SPI tasks to one core, the HTTP
-task to the other core.
+esp_http_client_set_header(http_client, "Range", buf);
+esp_http_client_perform(http_client);
+```
-Better, but screen updates are blocking user input; Made SPI transfer async:
+Page buffer: Three pages (prev/current/next) in RAM—maximum possible. On
+request: cycles buffer, updates screen, prefetches next page.
```
-void epd_draw_async(const uint8_t *buf, size_t n)
-{
- static spi_transaction_t t[3];
-
- memset(&t[0], 0, sizeof(t[0]));
- t[0].length = 8;
- t[0].tx_data[0] = 0x13;
- t[0].user = (void*) 0;
- t[0].flags = SPI_TRANS_USE_TXDATA;
-
- memset(&t[1], 0, sizeof(t[1]));
- t[1].length = 8 * n;
- t[1].tx_buffer = buf;
- t[1].user = (void*) 1;
-
- memset(&t[2], 0, sizeof(t[2]));
- t[2].length = 8;
- t[2].tx_data[0] = 0x12;
- t[2].user = (void*) 0;
- t[2].flags = SPI_TRANS_USE_TXDATA;
-
- for (int i = 0; i < 3; i++)
- spi_device_queue_trans(spi, &t[i], portMAX_DELAY);
-}
+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();
```
-Much better.
+Responsiveness: inadequate. 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.
-2023-10-06: Moved the page table to DMA-capable memory; Reclaimed a few more
-CPU cycles from the SPI transfers.
+Better, but screen updates block user input. Moved SPI buffers to DMA and made
+transfers async. Few more cycles saved.
Can't think of anything else.
-Verdict: Works but limited. Led to [Etlas](../etlas/).
+Verdict: Functional but limited. Led to [Etlas](../etlas/).
Commit:
[7f691c4](https://git.asciimx.com/esp32-e-reader/commit/?id=7f691c46093933b67aab466c0ca582ace8ab73d4)
diff --git a/_site/feed.xml b/_site/feed.xml
index 989f4b2..93d691d 100644
--- a/_site/feed.xml
+++ b/_site/feed.xml
@@ -1 +1 @@
-<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="/feed.xml" rel="self" type="application/atom+xml" /><link href="/" rel="alternate" type="text/html" /><updated>2026-01-04T22:36:11+08:00</updated><id>/feed.xml</id><title type="html">ASCIIMX | Log</title><author><name>W. D. Sadeep Madurange</name></author><entry><title type="html">Search engine (Perl + FastCGI + SA)</title><link href="/log/site-search/" rel="alternate" type="text/html" title="Search engine (Perl + FastCGI + SA)" /><published>2026-01-03T00:00:00+08:00</published><updated>2026-01-03T00:00:00+08:00</updated><id>/log/site-search</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Article count on the website is growing. Need a way to search.]]></summary></entry><entry><title type="html">Matrix Rain: 2025 refactor</title><link href="/log/matrix-digital-rain/" rel="alternate" type="text/html" title="Matrix Rain: 2025 refactor" /><published>2025-12-21T00:00:00+08:00</published><updated>2025-12-21T00:00:00+08:00</updated><id>/log/matrix-digital-rain</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[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.]]></summary></entry><entry><title type="html">Fingerprint door lock (LP)</title><link href="/log/fpm-door-lock-lp/" rel="alternate" type="text/html" title="Fingerprint door lock (LP)" /><published>2025-08-18T00:00:00+08:00</published><updated>2025-08-18T00:00:00+08:00</updated><id>/log/fpm-door-lock-lp</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[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.]]></summary></entry><entry><title type="html">High-side MOSFET switching</title><link href="/log/mosfet-switches/" rel="alternate" type="text/html" title="High-side MOSFET switching" /><published>2025-06-22T00:00:00+08:00</published><updated>2025-06-22T00:00:00+08:00</updated><id>/log/mosfet-switches</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[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.]]></summary></entry><entry><title type="html">ATmega328P at 3.3V and 5V</title><link href="/log/arduino-uno/" rel="alternate" type="text/html" title="ATmega328P at 3.3V and 5V" /><published>2025-06-10T00:00:00+08:00</published><updated>2025-06-10T00:00:00+08:00</updated><id>/log/arduino-uno</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Quick reference for wiring ATmega328P ICs at 5V and 3.3V. 5V uses 16MHz crystal, 3.3V uses 8MHz.]]></summary></entry><entry><title type="html">Fingerprint door lock (RF)</title><link href="/log/fpm-door-lock-rf/" rel="alternate" type="text/html" title="Fingerprint door lock (RF)" /><published>2025-06-05T00:00:00+08:00</published><updated>2025-06-05T00:00:00+08:00</updated><id>/log/fpm-door-lock-rf</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Wanted to unlock door with fingerprint, wirelessly to avoid drilling.]]></summary></entry><entry><title type="html">Bumblebee: browser automation</title><link href="/log/bumblebee/" rel="alternate" type="text/html" title="Bumblebee: browser automation" /><published>2025-04-02T00:00:00+08:00</published><updated>2025-04-02T00:00:00+08:00</updated><id>/log/bumblebee</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Built with Andy Zhang for an employer. Tool to automate web scraping script generation.]]></summary></entry><entry><title type="html">Bare-metal ATSAM3X8E</title><link href="/log/arduino-due/" rel="alternate" type="text/html" title="Bare-metal ATSAM3X8E" /><published>2024-09-16T00:00:00+08:00</published><updated>2024-09-16T00:00:00+08:00</updated><id>/log/arduino-due</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Notes on programming bare-metal ATSAM3X8E chips (Arduino Due) using Serial Wire Debug (SwD) protocol.]]></summary></entry><entry><title type="html">Etlas: e-paper dashboard</title><link href="/log/etlas/" rel="alternate" type="text/html" title="Etlas: e-paper dashboard" /><published>2024-09-05T00:00:00+08:00</published><updated>2024-09-05T00:00:00+08:00</updated><id>/log/etlas</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Repurposed e-reader prototype into something for regular use. News, stocks, weather dashboard. ESP32 NodeMCU D1 + 7.5” Waveshare e-paper + DHT22 sensor.]]></summary></entry><entry><title type="html">ESP32 e-reader prototype</title><link href="/log/e-reader/" rel="alternate" type="text/html" title="ESP32 e-reader prototype" /><published>2023-10-24T00:00:00+08:00</published><updated>2023-10-24T00:00:00+08:00</updated><id>/log/e-reader</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[First project with e-paper displays and ESP32.]]></summary></entry></feed> \ No newline at end of file
+<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="http://localhost:4000/feed.xml" rel="self" type="application/atom+xml" /><link href="http://localhost:4000/" rel="alternate" type="text/html" /><updated>2026-01-05T12:16:46+08:00</updated><id>http://localhost:4000/feed.xml</id><title type="html">ASCIIMX | Log</title><author><name>W. D. Sadeep Madurange</name></author><entry><title type="html">Search engine (Perl + FastCGI + SA)</title><link href="http://localhost:4000/log/site-search/" rel="alternate" type="text/html" title="Search engine (Perl + FastCGI + SA)" /><published>2026-01-03T00:00:00+08:00</published><updated>2026-01-03T00:00:00+08:00</updated><id>http://localhost:4000/log/site-search</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Article count on the website is growing. Need a way to search.]]></summary></entry><entry><title type="html">Matrix Rain: 2025 refactor</title><link href="http://localhost:4000/log/matrix-digital-rain/" rel="alternate" type="text/html" title="Matrix Rain: 2025 refactor" /><published>2025-12-21T00:00:00+08:00</published><updated>2025-12-21T00:00:00+08:00</updated><id>http://localhost:4000/log/matrix-digital-rain</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[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.]]></summary></entry><entry><title type="html">Fingerprint door lock (LP)</title><link href="http://localhost:4000/log/fpm-door-lock-lp/" rel="alternate" type="text/html" title="Fingerprint door lock (LP)" /><published>2025-08-18T00:00:00+08:00</published><updated>2025-08-18T00:00:00+08:00</updated><id>http://localhost:4000/log/fpm-door-lock-lp</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[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.]]></summary></entry><entry><title type="html">High-side MOSFET switching</title><link href="http://localhost:4000/log/mosfet-switches/" rel="alternate" type="text/html" title="High-side MOSFET switching" /><published>2025-06-22T00:00:00+08:00</published><updated>2025-06-22T00:00:00+08:00</updated><id>http://localhost:4000/log/mosfet-switches</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[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.]]></summary></entry><entry><title type="html">ATmega328P at 3.3V and 5V</title><link href="http://localhost:4000/log/arduino-uno/" rel="alternate" type="text/html" title="ATmega328P at 3.3V and 5V" /><published>2025-06-10T00:00:00+08:00</published><updated>2025-06-10T00:00:00+08:00</updated><id>http://localhost:4000/log/arduino-uno</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Quick reference for wiring ATmega328P ICs at 5V and 3.3V. 5V uses 16MHz crystal, 3.3V uses 8MHz.]]></summary></entry><entry><title type="html">Fingerprint door lock (RF)</title><link href="http://localhost:4000/log/fpm-door-lock-rf/" rel="alternate" type="text/html" title="Fingerprint door lock (RF)" /><published>2025-06-05T00:00:00+08:00</published><updated>2025-06-05T00:00:00+08:00</updated><id>http://localhost:4000/log/fpm-door-lock-rf</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Wanted to unlock door with fingerprint, wirelessly to avoid drilling.]]></summary></entry><entry><title type="html">Bumblebee: browser automation</title><link href="http://localhost:4000/log/bumblebee/" rel="alternate" type="text/html" title="Bumblebee: browser automation" /><published>2025-04-02T00:00:00+08:00</published><updated>2025-04-02T00:00:00+08:00</updated><id>http://localhost:4000/log/bumblebee</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Built with Andy Zhang for an employer. Tool to automate web scraping script generation.]]></summary></entry><entry><title type="html">Bare-metal ATSAM3X8E</title><link href="http://localhost:4000/log/arduino-due/" rel="alternate" type="text/html" title="Bare-metal ATSAM3X8E" /><published>2024-09-16T00:00:00+08:00</published><updated>2024-09-16T00:00:00+08:00</updated><id>http://localhost:4000/log/arduino-due</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Notes on programming bare-metal ATSAM3X8E chips (Arduino Due) using Serial Wire Debug (SwD) protocol.]]></summary></entry><entry><title type="html">Etlas: e-paper dashboard</title><link href="http://localhost:4000/log/etlas/" rel="alternate" type="text/html" title="Etlas: e-paper dashboard" /><published>2024-09-05T00:00:00+08:00</published><updated>2024-09-05T00:00:00+08:00</updated><id>http://localhost:4000/log/etlas</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Repurposed e-reader prototype into something for regular use. News, stocks, weather dashboard. ESP32 NodeMCU D1 + 7.5” Waveshare e-paper + DHT22 sensor.]]></summary></entry><entry><title type="html">ESP32 prototype e-reader</title><link href="http://localhost:4000/log/e-reader/" rel="alternate" type="text/html" title="ESP32 prototype e-reader" /><published>2023-10-24T00:00:00+08:00</published><updated>2023-10-24T00:00:00+08:00</updated><id>http://localhost:4000/log/e-reader</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[First project with e-paper displays and ESP32.]]></summary></entry></feed> \ No newline at end of file
diff --git a/_site/index.html b/_site/index.html
index ef782ee..cce84be 100644
--- a/_site/index.html
+++ b/_site/index.html
@@ -175,7 +175,7 @@
<tr>
<td class="posts-td posts-td-link">
- <a href="/log/e-reader/" class="link-decor-none">ESP32 e-reader prototype</a>
+ <a href="/log/e-reader/" class="link-decor-none">ESP32 prototype e-reader</a>
</td>
<td class="posts-td posts-td-time">
<span class="post-meta">
diff --git a/_site/log/e-reader/index.html b/_site/log/e-reader/index.html
index a5dbc01..41f58ff 100644
--- a/_site/log/e-reader/index.html
+++ b/_site/log/e-reader/index.html
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
- <title>ESP32 e-reader prototype</title>
+ <title>ESP32 prototype e-reader</title>
<link rel="stylesheet" href="/assets/css/main.css">
<link rel="stylesheet" href="/assets/css/skeleton.css">
</head>
@@ -37,7 +37,7 @@
<main>
<div class="container">
<div class="container-2">
- <h2 class="center" id="title">ESP32 E-READER PROTOTYPE</h2>
+ <h2 class="center" id="title">ESP32 PROTOTYPE E-READER</h2>
<h5 class="center">24 OCTOBER 2023</h5>
<br>
<div class="twocol justify"><p>First project with e-paper displays and ESP32.</p>
@@ -46,61 +46,51 @@
<source src="ereader.mp4" type="video/mp4" />
</video>
-<p>System: ESP-WROOM-32, 7.5” Waveshare e-paper display, three buttons
+<p>ESP-WROOM-32, 7.5” Waveshare e-paper display, three-button interface
(prev/next/sleep).</p>
-<p>2023-09-23: 512KB SRAM, 4MB flash (shared with FreeRTOS and ESP-IDF). Not
-enough storage for books. Using ESP32’s built-in WiFi to stream them over HTTP.
-Recording the reading progress in RTC memory.</p>
+<p>Memory: 512KB SRAM + 4MB flash–insufficient for local library. Streams via
+HTTP Range requests over WiFi. Reading progress saved to RTC memory; persists
+through deep sleep.</p>
-<p>Rasterized pages encoded as tightly packed bitmaps (1 byte =&gt; 8 pixels), no
-headers, arranged along 48 KB (480x800) boundaries; Reader can stream pages
-using HTTP Range requests with zero server-side logic. Keeps both ends lean.</p>
+<p>EBM format: Raw bitmap sequence. 1 byte = 8 pixels, 1 page = 48 KB (display
+resolution), headerless. Optimized for HTTP Range requests:</p>
-<p>Page table stores 3 pages (prev/current/next) in a circular buffer. When the
-user requests a page, program cycles through the table, updates the screen, and
-downloads the next page.</p>
+<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>int r0 = ((page_n - 1) * PAGE_SIZE);
+int rn = page_n * PAGE_SIZE - 1;
-<p>Responsiveness is inadequate. Scheduling GPIO (user input), SPI, and HTTP on
-one core causes input lag. Pinned the GPIO and SPI tasks to one core, the HTTP
-task to the other core.</p>
+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);
-<p>Better, but screen updates are blocking user input; Made SPI transfer async:</p>
-
-<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>void epd_draw_async(const uint8_t *buf, size_t n)
-{
- static spi_transaction_t t[3];
+esp_http_client_set_header(http_client, "Range", buf);
+esp_http_client_perform(http_client);
+</code></pre></div></div>
- memset(&amp;t[0], 0, sizeof(t[0]));
- t[0].length = 8;
- t[0].tx_data[0] = 0x13;
- t[0].user = (void*) 0;
- t[0].flags = SPI_TRANS_USE_TXDATA;
+<p>Page buffer: Three pages (prev/current/next) in RAM—maximum possible. On
+request: cycles buffer, updates screen, prefetches next page.</p>
- memset(&amp;t[1], 0, sizeof(t[1]));
- t[1].length = 8 * n;
- t[1].tx_buffer = buf;
- t[1].user = (void*) 1;
+<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>c_page_num++;
+pg.page_num = c_page_num + 2;
+pg.page_buf = pages[(c_page_num + 1) % PAGE_LEN];
- memset(&amp;t[2], 0, sizeof(t[2]));
- t[2].length = 8;
- t[2].tx_data[0] = 0x12;
- t[2].user = (void*) 0;
- t[2].flags = SPI_TRANS_USE_TXDATA;
+xSemaphoreGive(mutex);
+xQueueSend(http_evt_queue, &amp;pg, portMAX_DELAY);
- for (int i = 0; i &lt; 3; i++)
- spi_device_queue_trans(spi, &amp;t[i], portMAX_DELAY);
-}
+epd_draw_async(pages[c_page_num % PAGE_LEN], PAGE_SIZE);
+epd_draw_await();
</code></pre></div></div>
-<p>Much better.</p>
+<p>Responsiveness: inadequate. 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.</p>
-<p>2023-10-06: Moved the page table to DMA-capable memory; Reclaimed a few more
-CPU cycles from the SPI transfers.</p>
+<p>Better, but screen updates block user input. Moved SPI buffers to DMA and made
+transfers async. Few more cycles saved.</p>
<p>Can’t think of anything else.</p>
-<p>Verdict: Works but limited. Led to <a href="../etlas/">Etlas</a>.</p>
+<p>Verdict: Functional but limited. Led to <a href="../etlas/">Etlas</a>.</p>
<p>Commit:
<a href="https://git.asciimx.com/esp32-e-reader/commit/?id=7f691c46093933b67aab466c0ca582ace8ab73d4">7f691c4</a></p>
diff --git a/_site/posts.xml b/_site/posts.xml
index 47d8e4d..97210e4 100644
--- a/_site/posts.xml
+++ b/_site/posts.xml
@@ -1 +1 @@
-<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="/posts.xml" rel="self" type="application/atom+xml" /><link href="/" rel="alternate" type="text/html" /><updated>2026-01-04T22:36:11+08:00</updated><id>/posts.xml</id><title type="html">ASCIIMX</title><author><name>W. D. Sadeep Madurange</name></author></feed> \ No newline at end of file
+<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="http://localhost:4000/posts.xml" rel="self" type="application/atom+xml" /><link href="http://localhost:4000/" rel="alternate" type="text/html" /><updated>2026-01-05T12:16:46+08:00</updated><id>http://localhost:4000/posts.xml</id><title type="html">ASCIIMX</title><author><name>W. D. Sadeep Madurange</name></author></feed> \ No newline at end of file
diff --git a/_site/projects/index.html b/_site/projects/index.html
index 6bffe61..6e6c5be 100644
--- a/_site/projects/index.html
+++ b/_site/projects/index.html
@@ -103,8 +103,8 @@
<td class="project-item">
<a href="../log/e-reader" class="link-decor-none">
- <img src="../log/e-reader/thumb_sm.png" alt="ESP32 e-reader prototype">
- <h5>ESP32 e-reader prototype</h5>
+ <img src="../log/e-reader/thumb_sm.png" alt="ESP32 prototype e-reader">
+ <h5>ESP32 prototype e-reader</h5>
</a>
</td>
diff --git a/_site/robots.txt b/_site/robots.txt
index e087884..d297064 100644
--- a/_site/robots.txt
+++ b/_site/robots.txt
@@ -1 +1 @@
-Sitemap: /sitemap.xml
+Sitemap: http://localhost:4000/sitemap.xml
diff --git a/_site/sitemap.xml b/_site/sitemap.xml
index ad3bdcd..a722c6a 100644
--- a/_site/sitemap.xml
+++ b/_site/sitemap.xml
@@ -1,56 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
-<loc>/log/neo4j-a-star-search/</loc>
+<loc>http://localhost:4000/log/neo4j-a-star-search/</loc>
<lastmod>2018-03-06T00:00:00+08:00</lastmod>
</url>
<url>
-<loc>/log/e-reader/</loc>
+<loc>http://localhost:4000/log/e-reader/</loc>
<lastmod>2023-10-24T00:00:00+08:00</lastmod>
</url>
<url>
-<loc>/log/etlas/</loc>
+<loc>http://localhost:4000/log/etlas/</loc>
<lastmod>2024-09-05T00:00:00+08:00</lastmod>
</url>
<url>
-<loc>/log/arduino-due/</loc>
+<loc>http://localhost:4000/log/arduino-due/</loc>
<lastmod>2024-09-16T00:00:00+08:00</lastmod>
</url>
<url>
-<loc>/log/bumblebee/</loc>
+<loc>http://localhost:4000/log/bumblebee/</loc>
<lastmod>2025-04-02T00:00:00+08:00</lastmod>
</url>
<url>
-<loc>/log/fpm-door-lock-rf/</loc>
+<loc>http://localhost:4000/log/fpm-door-lock-rf/</loc>
<lastmod>2025-06-05T00:00:00+08:00</lastmod>
</url>
<url>
-<loc>/log/arduino-uno/</loc>
+<loc>http://localhost:4000/log/arduino-uno/</loc>
<lastmod>2025-06-10T00:00:00+08:00</lastmod>
</url>
<url>
-<loc>/log/mosfet-switches/</loc>
+<loc>http://localhost:4000/log/mosfet-switches/</loc>
<lastmod>2025-06-22T00:00:00+08:00</lastmod>
</url>
<url>
-<loc>/log/fpm-door-lock-lp/</loc>
+<loc>http://localhost:4000/log/fpm-door-lock-lp/</loc>
<lastmod>2025-08-18T00:00:00+08:00</lastmod>
</url>
<url>
-<loc>/log/matrix-digital-rain/</loc>
+<loc>http://localhost:4000/log/matrix-digital-rain/</loc>
<lastmod>2025-12-21T00:00:00+08:00</lastmod>
</url>
<url>
-<loc>/log/site-search/</loc>
+<loc>http://localhost:4000/log/site-search/</loc>
<lastmod>2026-01-03T00:00:00+08:00</lastmod>
</url>
<url>
-<loc>/about/</loc>
+<loc>http://localhost:4000/about/</loc>
</url>
<url>
-<loc>/</loc>
+<loc>http://localhost:4000/</loc>
</url>
<url>
-<loc>/projects/</loc>
+<loc>http://localhost:4000/projects/</loc>
</url>
</urlset>