summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--_projects/e-reader.md69
-rw-r--r--_site/assets/css/main.css15
-rw-r--r--_site/feed.xml2
-rw-r--r--_site/posts.xml2
-rw-r--r--_site/projects/e-reader/index.html67
-rw-r--r--assets/css/main.css15
6 files changed, 87 insertions, 83 deletions
diff --git a/_projects/e-reader.md b/_projects/e-reader.md
index cefbb03..9598e46 100644
--- a/_projects/e-reader.md
+++ b/_projects/e-reader.md
@@ -5,34 +5,30 @@ thumbnail: thumb.png
layout: post
---
-This project features a minimal e-reader powered by an ESP-WROOM-32 development
-board and a 7.5-inch <a href="https://www.waveshare.com/" class="external"
-target="_blank" rel="noopener noreferrer">Waveshare</a> e-paper display built
-with the intention of learning about e-paper displays.
+This project features an experimental e-reader powered by an ESP-WROOM-32
+development board and a 7.5-inch <a href="https://www.waveshare.com/"
+class="external" target="_blank" rel="noopener noreferrer">Waveshare</a>
+e-paper display built with the intention of learning about e-paper displays.
<video style="max-width:100%;" controls="" poster="thumb.png">
<source src="ereader.mp4" type="video/mp4">
</video>
-## Overview
+## Introduction
-In 2017, I was tasked with installing some e-paper displays in a car park. Not
-knowing how they worked, I remember marveling at their sight like a Muggle
-witnessing magic. As someone who enjoys reading, I found e-paper to be a true
-innovation. This project was born out of that enduring curiosity and love of
-e-paper technology.
+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 prototype, while far from ready for daily use, has some nifty features that
-fellow hobbyists and tinkerers may find interesting. The reader can display
-books of arbitrary sizes by streaming them over HTTP. It employs sleep modes to
-minimize power consumption when not in use and records the reading progress in
-the chip's RTC memory.
-
-The most formidable challenge when trying to build an e-reader with an ESP32
-board is its limited memory and storage. My ESP-WROOM-32 board has 512KB of
-SRAM and 4MB of flash memory, which the freeRTOS, ESP-IDF, and the e-reader
+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.
+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
@@ -69,26 +65,29 @@ 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's task API to distribute the two
-tasks between the available cores to make the reader more responsive.
+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.
-## Reflections
-
-It's been six years since the car park and the displays. I began this project
-hoping to learn more about e-paper displays, and I got that and more. By
-working within the constraints of the ESP32, I forced myself to explore some of
-its advanced features: sleep modes, multicore task scheduling, DMA transfers,
-and RTC memory.
-
-As for the prototype, while it's no match for a commercial e-reader with
-features like an offline library of books and touch screens, there's something
-to be said about reading on hardware you built yourself. You are no longer the
-powerless Muggle watching others perform magic. You are the wizard who makes
-the invisible particles swirl into form by whispering C to them.
+## 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](source.tar.gz)
diff --git a/_site/assets/css/main.css b/_site/assets/css/main.css
index 5a777c0..46139c8 100644
--- a/_site/assets/css/main.css
+++ b/_site/assets/css/main.css
@@ -22,12 +22,15 @@ body {
text-shadow: 0 0 1px var(--main-fg-color), 0 0 6px var(--main-fg-color);
}
-body::selection {
- background: lightgrey;
-}
-
-p::selection {
- background: lightgrey;
+::selection {
+ color: var(--main-bg-color);
+ background: var(--main-fg-color);
+ text-shadow: 0 0 1px var(--main-bg-color), 0 0 6px var(--main-bg-color);
+}
+::-moz-selection {
+ color: var(--main-bg-color);
+ background: var(--main-fg-color);
+ text-shadow: 0 0 1px var(--main-bg-color), 0 0 6px var(--main-bg-color);
}
.footer {
diff --git a/_site/feed.xml b/_site/feed.xml
index 850bb0c..ec30baf 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>2025-12-17T07:12:59+08:00</updated><id>/feed.xml</id><title type="html">ASCIIMX | Blog</title><author><name>W. D. Sadeep Madurange</name></author><entry><title type="html">How I manage Suckless software installations</title><link href="/blog/suckless-software/" rel="alternate" type="text/html" title="How I manage Suckless software installations" /><published>2025-11-30T00:00:00+08:00</published><updated>2025-11-30T00:00:00+08:00</updated><id>/blog/suckless-software</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Since suckless software requires users to modify the source code and recompile to customize, I need a way to maintain patches over the long term while retaining the ability to upgrade the software as new versions are released.]]></summary></entry><entry><title type="html">Neo4J A* search</title><link href="/blog/neo4j-a-star-search/" rel="alternate" type="text/html" title="Neo4J A* search" /><published>2025-09-14T00:00:00+08:00</published><updated>2025-09-14T00:00:00+08:00</updated><id>/blog/neo4j-a-star-search</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Back in 2018, we used Neo4J graph database to track the movement of marine vessels. We were interested in the shortest path a ship could take through a network of about 13,000 route points. Algorithms based on graph theory, such as A* search, provide optimal solutions to such problems. In other words, the set of route points lends itself well to a model based on graphs.]]></summary></entry><entry><title type="html">MOSFETs as electronic switches</title><link href="/blog/mosfet-switches/" rel="alternate" type="text/html" title="MOSFETs as electronic switches" /><published>2025-06-22T00:00:00+08:00</published><updated>2025-06-22T00:00:00+08:00</updated><id>/blog/mosfet-switches</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Recently, I needed a low-power circuit for one of my battery-operated projects. Much of the system’s power savings depended on its ability to electronically switch off components, such as servos, that draw high levels of quiescent currents. My search for a solution led me to MOSFETs, transistors capable of controlling circuits operating at voltages far above their own.]]></summary></entry><entry><title type="html">How to configure ATmega328P microcontrollers to run at 3.3V and 5V</title><link href="/blog/arduino-uno/" rel="alternate" type="text/html" title="How to configure ATmega328P microcontrollers to run at 3.3V and 5V" /><published>2025-04-10T00:00:00+08:00</published><updated>2025-04-10T00:00:00+08:00</updated><id>/blog/arduino-uno</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[This is a quick reference for wiring up ATmega328P ICs to run at 5V and 3.3V. While the 5V configuration is common, the 3.3V configuration can be useful in low-power applications and when interfacing with parts that themselves run at 3.3V. In this guide, the 5V setup is configured with a 16MHz crystal oscillator, while the 3.3V configuration makes use of an 8MHz crystal oscillator.]]></summary></entry><entry><title type="html">How to set up ATSAM3X8E microcontrollers for bare-metal programming in C</title><link href="/blog/arduino-due/" rel="alternate" type="text/html" title="How to set up ATSAM3X8E microcontrollers for bare-metal programming in C" /><published>2024-10-05T00:00:00+08:00</published><updated>2024-10-05T00:00:00+08:00</updated><id>/blog/arduino-due</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[This article is a step-by-step guide for programming bare-metal ATSAM3X8E chips found on Arduino Due boards. It also includes notes on the chip’s memory layout relevant for writing linker scripts. The steps described in this article were tested on an OpenBSD workstation.]]></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="/feed.xml" rel="self" type="application/atom+xml" /><link href="/" rel="alternate" type="text/html" /><updated>2025-12-17T22:22:01+08:00</updated><id>/feed.xml</id><title type="html">ASCIIMX | Blog</title><author><name>W. D. Sadeep Madurange</name></author><entry><title type="html">How I manage Suckless software installations</title><link href="/blog/suckless-software/" rel="alternate" type="text/html" title="How I manage Suckless software installations" /><published>2025-11-30T00:00:00+08:00</published><updated>2025-11-30T00:00:00+08:00</updated><id>/blog/suckless-software</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Since suckless software requires users to modify the source code and recompile to customize, I need a way to maintain patches over the long term while retaining the ability to upgrade the software as new versions are released.]]></summary></entry><entry><title type="html">Neo4J A* search</title><link href="/blog/neo4j-a-star-search/" rel="alternate" type="text/html" title="Neo4J A* search" /><published>2025-09-14T00:00:00+08:00</published><updated>2025-09-14T00:00:00+08:00</updated><id>/blog/neo4j-a-star-search</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Back in 2018, we used Neo4J graph database to track the movement of marine vessels. We were interested in the shortest path a ship could take through a network of about 13,000 route points. Algorithms based on graph theory, such as A* search, provide optimal solutions to such problems. In other words, the set of route points lends itself well to a model based on graphs.]]></summary></entry><entry><title type="html">MOSFETs as electronic switches</title><link href="/blog/mosfet-switches/" rel="alternate" type="text/html" title="MOSFETs as electronic switches" /><published>2025-06-22T00:00:00+08:00</published><updated>2025-06-22T00:00:00+08:00</updated><id>/blog/mosfet-switches</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Recently, I needed a low-power circuit for one of my battery-operated projects. Much of the system’s power savings depended on its ability to electronically switch off components, such as servos, that draw high levels of quiescent currents. My search for a solution led me to MOSFETs, transistors capable of controlling circuits operating at voltages far above their own.]]></summary></entry><entry><title type="html">How to configure ATmega328P microcontrollers to run at 3.3V and 5V</title><link href="/blog/arduino-uno/" rel="alternate" type="text/html" title="How to configure ATmega328P microcontrollers to run at 3.3V and 5V" /><published>2025-04-10T00:00:00+08:00</published><updated>2025-04-10T00:00:00+08:00</updated><id>/blog/arduino-uno</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[This is a quick reference for wiring up ATmega328P ICs to run at 5V and 3.3V. While the 5V configuration is common, the 3.3V configuration can be useful in low-power applications and when interfacing with parts that themselves run at 3.3V. In this guide, the 5V setup is configured with a 16MHz crystal oscillator, while the 3.3V configuration makes use of an 8MHz crystal oscillator.]]></summary></entry><entry><title type="html">How to set up ATSAM3X8E microcontrollers for bare-metal programming in C</title><link href="/blog/arduino-due/" rel="alternate" type="text/html" title="How to set up ATSAM3X8E microcontrollers for bare-metal programming in C" /><published>2024-10-05T00:00:00+08:00</published><updated>2024-10-05T00:00:00+08:00</updated><id>/blog/arduino-due</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[This article is a step-by-step guide for programming bare-metal ATSAM3X8E chips found on Arduino Due boards. It also includes notes on the chip’s memory layout relevant for writing linker scripts. The steps described in this article were tested on an OpenBSD workstation.]]></summary></entry></feed> \ No newline at end of file
diff --git a/_site/posts.xml b/_site/posts.xml
index 7a71ed1..87b163b 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>2025-12-17T07:12:59+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="/posts.xml" rel="self" type="application/atom+xml" /><link href="/" rel="alternate" type="text/html" /><updated>2025-12-17T22:22:01+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
diff --git a/_site/projects/e-reader/index.html b/_site/projects/e-reader/index.html
index ea997c4..46e5f21 100644
--- a/_site/projects/e-reader/index.html
+++ b/_site/projects/e-reader/index.html
@@ -44,33 +44,29 @@
<h2 class="center" id="title">EXPERIMENTAL E-READER</h2>
<h6 class="center">24 OCTOBER 2023</h5>
<br>
- <div class="twocol justify"><p>This project features a minimal e-reader powered by an ESP-WROOM-32 development
-board and a 7.5-inch <a href="https://www.waveshare.com/" class="external" target="_blank" rel="noopener noreferrer">Waveshare</a> e-paper display built
-with the intention of learning about e-paper displays.</p>
+ <div class="twocol justify"><p>This project features an experimental e-reader powered by an ESP-WROOM-32
+development board and a 7.5-inch <a href="https://www.waveshare.com/" class="external" target="_blank" rel="noopener noreferrer">Waveshare</a>
+e-paper display built with the intention of learning about e-paper displays.</p>
<video style="max-width:100%;" controls="" poster="thumb.png">
<source src="ereader.mp4" type="video/mp4" />
</video>
-<h2 id="overview">Overview</h2>
+<h2 id="introduction">Introduction</h2>
-<p>In 2017, I was tasked with installing some e-paper displays in a car park. Not
-knowing how they worked, I remember marveling at their sight like a Muggle
-witnessing magic. As someone who enjoys reading, I found e-paper to be a true
-innovation. This project was born out of that enduring curiosity and love of
-e-paper technology.</p>
+<p>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.</p>
-<p>The prototype, while far from ready for daily use, has some nifty features that
-fellow hobbyists and tinkerers may find interesting. The reader can display
-books of arbitrary sizes by streaming them over HTTP. It employs sleep modes to
-minimize power consumption when not in use and records the reading progress in
-the chip’s RTC memory.</p>
-
-<p>The most formidable challenge when trying to build an e-reader with an ESP32
-board is its limited memory and storage. My ESP-WROOM-32 board has 512KB of
-SRAM and 4MB of flash memory, which the freeRTOS, ESP-IDF, and the e-reader
+<p>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.</p>
+at least 256MB of memory and 8GB of storage. That is 500x more memory than what
+I’d have to work with.</p>
<p>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
@@ -107,27 +103,30 @@ 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’s task API to distribute the two
-tasks between the available cores to make the reader more responsive.</p>
+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.</p>
<p>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.</p>
-<h2 id="reflections">Reflections</h2>
-
-<p>It’s been six years since the car park and the displays. I began this project
-hoping to learn more about e-paper displays, and I got that and more. By
-working within the constraints of the ESP32, I forced myself to explore some of
-its advanced features: sleep modes, multicore task scheduling, DMA transfers,
-and RTC memory.</p>
-
-<p>As for the prototype, while it’s no match for a commercial e-reader with
-features like an offline library of books and touch screens, there’s something
-to be said about reading on hardware you built yourself. You are no longer the
-powerless Muggle watching others perform magic. You are the wizard who makes
-the invisible particles swirl into form by whispering C to them.</p>
+<h2 id="epilogue">Epilogue</h2>
+
+<p>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.</p>
+
+<p>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.</p>
<p>Files: <a href="source.tar.gz">source.tar.gz</a></p>
</div>
diff --git a/assets/css/main.css b/assets/css/main.css
index 5a777c0..46139c8 100644
--- a/assets/css/main.css
+++ b/assets/css/main.css
@@ -22,12 +22,15 @@ body {
text-shadow: 0 0 1px var(--main-fg-color), 0 0 6px var(--main-fg-color);
}
-body::selection {
- background: lightgrey;
-}
-
-p::selection {
- background: lightgrey;
+::selection {
+ color: var(--main-bg-color);
+ background: var(--main-fg-color);
+ text-shadow: 0 0 1px var(--main-bg-color), 0 0 6px var(--main-bg-color);
+}
+::-moz-selection {
+ color: var(--main-bg-color);
+ background: var(--main-fg-color);
+ text-shadow: 0 0 1px var(--main-bg-color), 0 0 6px var(--main-bg-color);
}
.footer {