summaryrefslogtreecommitdiffstats
path: root/_site/projects/e-reader/index.html
blob: 9d26ee23d2d1edf365f78af32dbc1e4f59a71a35 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Experimental e-reader</title>

    <head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Experimental e-reader</title>
  <link rel="stylesheet" href="/assets/css/main.css">
  <link rel="stylesheet" href="/assets/css/skeleton.css">
</head>



  </head>
  <body>

    <div id="nav-container" class="container">
  <ul id="navlist" class="left">
    
    <li >
      <a href="/" class="link-decor-none">hme</a>
    </li>
    <li >
      <a href="/blog/" class="link-decor-none">blg</a>
    </li>
    <li class="active">
      <a href="/projects/" class="link-decor-none">poc</a>
    </li>
    <li >
      <a href="/about/" class="link-decor-none">abt</a>
    </li>
    <li><a href="/feed.xml" class="link-decor-none">rss</a></li>
  </ul>
</div>



    <main>
      <div class="container">
        <div class="container-2">
          <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>

<video style="max-width:100%;" controls="" poster="thumb.png">
  <source src="ereader.mp4" type="video/mp4" />
</video>

<h2 id="overview">Overview</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, 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 512 KB of
SRAM and 4 MB 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 256 MB of memory and 8 GB of storage.</p>

<p>Despite its size, as microcontrollers go, ESP32 is a powerful system-on-a-chip
with a 160 MHz 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.</p>

<h2 id="the-file-format">The file format</h2>

<p>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).</p>

<p>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 48 KB
boundaries. This simple file format lends well to HTTP streaming, which is its
main advantage, as we will soon see.</p>

<p>The pdftoebm.py script enclosed in the tarball at the end of the page converts
PDF documents to EBM files.</p>

<h2 id="how-does-it-work">How does it work?</h2>

<p>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
<code class="language-plaintext highlighter-rouge">EBM_ARCH_URL</code> 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
<code class="language-plaintext highlighter-rouge">EBM_ARCH_URL</code> value. The latter requires us to recompile the embedded
software.</p>

<p>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’s task API to distribute the two
tasks between the available cores 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 it.</p>

<p>Files: <a href="source.tar.gz">source.tar.gz</a></p>
</div>
          <p class="post-author right">by W. D. Sadeep Madurange</p>
        </div>
      </div>
    </main>

    <div class="footer">
  <div class="container">
    <div class="twelve columns right container-2">
      <p id="footer-text">&copy; ASCIIMX - 2025</p>
    </div>
  </div>
</div>


  </body>
</html>