Music Reader
For years I have been seeing various music readers for sale, at
varying prices and quality levels, but nothing has floated my
boat because the screens simply aren't big enough, and I wanted an
E-Ink display ever since I first saw one.
I finally determined to build my own. (Versus buy Gvido, PadMu, ...)
Waveshare had some nice
10.3"
raw displays at $150 each, I bought two on Thursday, February 4,
2021. These particular displays were fairly large (roughly
8¼"×6¼" active area) and not too badly
priced, and they also had a high pixel density (1872×1404),
16-level gray scale (probably not necessary or useful here), and,
perhaps most importantly, a sub-second update time. Veeeeery
interesting. There are larger 12" units available, but they have
substantially fewer pixels and much longer update times.
Two of these in landscape orientation, stacked vertically, should give
a very nice composite portrait display 'page'. The strip in the
middle where the panels meet would be unpleasant for photographs and
standard display work, but for music, which is really usually
just a series of 8–10 stacked independent lines
(staves) on a page, that little extra gap in the middle would be no
big deal if effectively managed. Also, you can separately paginate
the two panels. Stomp on the foot pedal and it'd alternately update
the two stacked panels. Basically you'd read halfway down the page
and stomp, continue reading/playing on to the bottom while the upper
panel updates, then jump upwards to the next half page which should be
ready by then, and stomp again—ad infinitum. (My ultimate
vision is four such panels in an open folder configuration, then you'd
alternately update left/right pages instead of top/bottom page
halves.)
Drive the whole thing with a Raspberry Pi of some sort, or equivalent.
Recent work (for Silverwood) showed how easy it is to drive these
e-Ink (e-Paper) displays with the RPi, and the display quality is
unequalled. Put it all in a hinged case with a sufficient battery and
a little bit of custom software to handle the PDF's. An arrow-key
control panel with a few extra buttons to run the menu/selection
system. And a plug for the up/down foot switch. Magsafe technology?
(I really don't like wireless technology.) This project sounds like
a lot of fun, and might make a nice Christmas gift for the
professional musician in your family.
As I see it, this would have some fairly significant flaws:
- The case would likely be bulky and crude compared to commercial
offerings.
- Useless in the dark.
- No markup capabilities.
Two of these, at least, aren't much of a problem:
- Music is almost always used on a music stand. The bulk isn't
actually much of an issue.
The Manhasset stands we favor are
stout.
- Paper doesn't work in the dark either, but stand lights exist so
that should be fine.
(The lack of generating its own light means
the battery would have an easier time of it.)
- <Crickets...>
No, if anything is going to be a killer it's the lack of markup.
You'll have to take notes offline, so to speak, and annotate the PDF's
later and re-load them onto the reader. Too Bad.
Design Notes
-
The RPi has two SPI ports, you could use one for each display,
allowing parallel updating when required, for a faster full (initial)
update. For the 4-panel version just bank-select the two ports
between the left and right sides' display panels, using other I/O
pins as SPI chip selects.
-
In-bezel switches, perhaps on top, for menu operation. (On top
they're easier to push without disturbing the music stand than pushing
perpendicular to the face would be.)
-
A minimum of 6 switches. Four arrows, a Select button, and an
Escape/Menu/Exit button. Plus power switch and LED.
The Clunkdraw library allows for great
ability to design simple and attractive operating menus.
-
Bezel switch order: Menu Up Select Down Left Right. That puts the
ones you need most on the ends, where they can be found by touch.
-
A folding 4-panel unit should have two foot-switch ports, and a mode
where standmates could share the unit as two independent systems, each
operating in half-page mode. Should it have two sets of bezel
switches? Seems like it would need to, if shared mode was going to be
viable.
-
The left/right arrow keys would work equivalently to the foot switch.
-
Needs to be fairly weatherproof in case of sprinkles. Most musicians
would not play in the rain, but it'd be nice be able to to put away
the instruments first in case of a Weather Surprise.
-
Battery life needs to be at least a full day of operation. Charge
from USB port. Must be able to work normally while charging.
-
Need to find a way to put a RPi to sleep, or other low-power mode.
The displays need no power while not being changed, but you can't have
the controller suck all the juice out of the batteries while it's
merely waiting for keypresses. Needs a fast wakeup time, driven by
the switches. With sufficient battery maybe this wouldn't be an issue.
-
Power switch is push/pull on face of bezel. If you close it up it
pushes in the switch, turning it off. Batteries will not be killed by
accident while in storage.
-
Power/activity LED visible so you know it's on while it's booting.
This is an RPi, or whatever, and it's going to have some amount of
startup time before the displays can possibly react. An LED means
there's a chance you won't interfere with it while it's starting up.
-
Wakes up demanding a numeric passcode. The bezel switches could be
numbered, in addition to their normal function. Theft protection.
-
Once past the passcode, it goes to main menu screen. Main menu allows
setting any operating modes, as well as selecting from available
music.
Once music is chosen, it's in a music display mode where all you can
do is fore/aft using arrows or foot switch. Won't page forward from
end of music. Re-enter menu with Menu button. Select a power-down
mode before turning off. (Weak, but what are you going to do?)
-
Need a way to browse entire library of music, and select/de-select
them for use in a set list. That way you don't normally have to
browse through a large list to find the next piece in a set, and
you're not tempted to dump music just to eliminate the clutter.
-
Multiple saved set lists? Enhancement.
-
Music all stored on an external USB stick. Doesn't cause the RPi
heartburn by filling up its (writeable?) internal SD card storage. The
music store is read-only while inserted into the reader. It can get
fairly full without adversely impacting its performance or lifetime.
-
External music store is amended, offline, using any personal computer.
Reader doesn't need an extensive updating mechanism. Just scan what it
finds in the store at startup, and deal.
-
Need to be able to process PDF (or other?) scans. Online? Offline?
At the very least find the center split point and clean off the
margins. If it can be sliced into individual lines even better. If
each line can be sliced in half horizontally that gives you a
magnification option where each line can be shown blown up by
2×. (You'd want to split on bar lines.) In a perfect world bar
line splits that can be auto-identified would give you more
magnification options, but that's probably for a future day. Keeping
the original print line splits would probably be best, for tracking
with the original music.
-
Nice to be able to organize music in store by multiple means. Name,
composer, tagged date (school quarter, etc.), set... Multiple names?
(Think Karl's band where he calls out #3 instead of its name.) Extfs
format USB sticks could do hard links. FAT format sticks could not.
-
Raspberry Pi's do not have sleep/wakeup capabilities. They suck power
at all times. The 4B draws maybe 575mA at idle. However, there are
things you can do to turn off various peripherals to get the power
down considerably, if you're not using them. Consider:
# Turn off USB (and Ethernet) power, saves maybe 200mA? No USB flash, though.
echo 0 | sudo tee /sys/devices/platform/soc/3f980000.usb/buspower >/dev/null
# Turn off wifi/bluetooth. (unblock to bring it back.)
sudo rfkill block all
# Turn off HDMI.
/usr/bin/tvservice -o
-
The 4B has a fast (1.5GHz) quad-core CPU. Multiple cores, assuming
multiple SPI ports are there (and can be used, and don't interfere
with each other), will probably make parallel updating of the two
display panels very possible. There should be no significant use for
more than one core in this reader, otherwise.
-
The 0 has a 1GHz single-core BCM2835 CPU, and by far the lowest power
requirements in the Pi line. It has a single USB port, enough for the
only planned USB peripheral: the music store. Two SPI buses are
available on the 40-pin header. SPI0 has 2 CS pins, SPI1 has 3.
Enough to hook up 4 SPI E-Paper panels directly. Other I/O is still
left for the pushbuttons. Physically it is also quite small.
Assuming that the performance driving two (four?) displays is
adequate, this is clearly the best choice for the reader, power-wise.
Assuming that the SPI devices and drivers are decently implemented
(buffering/DMA/Interrupt), it should be possible to drive both SPI
busses in parallel using the single CPU core. (Forked or threaded
process?)
The 512MB RAM of the 0 is likely to be the most limiting factor, in
the end.
-
The 1872×1404 display panels want 328,536 bytes of
1-bit-per-monochrome-pixel buffer per display, which is an
awful lot, especially ×4 (1,314,144 bytes). One buffer could be
shared amongst all of the displays, relying upon the non-volatility of
the e-Paper panels, but then they'd definitely not be able to update
in parallel. Each display change would have to start from scratch
with a clear buffer.
-
A large Arduino offers some significant operational advantages over RPi:
- Fast boot
- Sleep/Wakeup
- No shutdown requirements
But comes with some significant disadvantages:
- Insufficient storage
- Slow clock
- No Pascal compiler
More RAM can be added, but might end up needing bank-switching and the
like. The necessary display buffering is huge, probably far beyond
what any Arduino could effectively work with. Clunkdraw would have to
be ported again, back to C.
-
An RPi can be operated in 'bare metal' mode by replacing the OS kernel
with a custom-crafted user application. This might be practical here,
but would be a significant amount of work. (The point would be faster
booting, and possibly sleep/wakeup.) Because none of the OS services
would be available, something 'simple' like the music store on USB stick
would require sucking the filesystem code into the application.
Something like DNIX's single-user mode would be nice for a bare-metal
application, but there is no such thing under Linux. (An 'OS' that
allowed normally-built but basic applications to run in a much simpler
non-paging single-tasking environment. Not practical here, in large
part because Linux world assumes that much more is always available to
applications, like access to vast numbers of shared code libraries.
Avoiding forking was about all you had to do under DNIX. Single-user
mode even offered an operating filesystem.)
The Ultibo environment, an embedded
environment for Raspberry Pi hardware, looks very interesting
for this. (Similar to Arduino, but with more CPU and RAM resources,
and minus the wretched toy-grade coding model.) The main claim to
fame is a 2-second boot time. Ultibo is written in Free Pascal, and
has a (specialized) Lazarus IDE. If the application were carefully
coded, this could essentially eliminate any shutdown requirements.
(Just kill the power when you're done playing.)
The
showmewebcam
project offers a stripped-down RPi environment that boots in about 10
seconds. That, or some variant thereof, could also be practical.
This environment runs from a read-only boot partition and could
essentially eliminate any shutdown requirements. (Just kill the
power when you're done playing.)
These two available RPi environments essentially blow any Arduino
solution out of the water.
-
If sufficient battery can be provided, the RPi 4B is the clear winner
here. Faster performance and easier development. OTOH, the 0's are
just so cool, cheap, and small—it would be quite the
coup to make one of those work out...
-
For better reactivity, the system should cache (image) the next page
in advance, so that the anticipated page update can be immediate.
Similarly, the previous page should be kept (and/or re-imaged) so
paging backwards is equally 'fast'. If system memory is sufficient,
all rendered pages could be kept.
This could even be extended to cacheing these
renderings in-flash—file timestamps could be checked to
see when cached files should be discarded.
E-Paper Mode Declaration
Contents copied here to protect against bit-rot of the
Original Document.
1. Description and Scope
This document applies to the AF E Ink waveform flash memory file. The
waveform flash file is designed for use with an E Ink approved
compatible controller (with advanced Generation II capabilities), an E
Ink approved Power Management Integrated Circuit (PMIC), and an Active
Matrix Electronic Paper Display (AMEPD) panel using E Ink Carta
Imaging Film. Verified AMEPDs are listed in Section 5. The AF waveform
is a high performance 4-bit (16-level) grayscale waveform. The AF
waveform look-up tables are defined in a 5-bit (32-level) pixel state
representation where the 16 graytones are assigned to the even pixel
states (0, 2, 4, ... 30), where 0 is black and 30 is white.
The waveform flash memory file contains temperature look-up tables
(LUTs), waveform sequence data, algorithm data, voltage data,
controller settings, and manufacturing data. Each AF waveform is
specifically adjusted for a particular display module lot. This
specification document is for use by E Ink Corporation and their
customers under non-disclosure agreements. E Ink Corporation will be
responsible for maintaining and controlling specification revisions.
2. Waveform Flash File Format
2.1 Introduction
The controller generates display waveforms using an internal or
external flash file. The waveform flash file contains multiple
temperatures look-up-tables (LUTs). Each temperature LUT contains the
waveform sequence information to allow the controller to properly
construct a waveform used to generate images on the display. Several
update modes are encoded in the AF waveform within each temperature
LUT.
2.2 Pixel State Usage
For the AF waveform, the LUTs are defined for a 5-bit (32-level) pixel
state representation. Graytones 1-16 are assigned to the even pixel
states (0, 2, 4, ... 30), respectively. The odd pixels states (1, 3,
5, ... 27) are not used. Odd pixel states 29 and 31 (along with state
30) are used to denote graytone 16; states 29 and 31 are used to
invoke special transitions to graytone 16.
2.3 Display Update Modes
2.3.1 INIT
The initialization (INIT) mode is used to completely erase the display
and leave it in the white state. It is useful for situations where the
display information in memory is not a faithful representation of the
optical state of the display, for example, after the device receives
power after it has been fully powered down. This waveform switches the
display several times and leaves it in the white state.
2.3.2 DU
The direct update (DU) is a very fast, non-flashy update. This mode
supports transitions from any graytone to black or white only. It
cannot be used to update to any graytone other than black or
white. The fast update time for this mode makes it useful for response
to touch sensor or pen input or menu selection indictors.
2.3.3 GC16
The grayscale clearing (GC16) mode is used to update the full display
and provide a high image quality. When GC16 is used with Full Display
Update the entire display will update as the new image is written. If
a Partial Update command is used the only pixels with changing
graytone values will update. The GC16 mode has 16 unique gray levels.
2.3.4 GL16
The GL16 waveform is primarily used to update sparse content on a
white background, such as a page of anti-aliased text, with reduced
flash. The GL16 waveform has 16 unique gray levels.
2.3.5 GLR16
The GLR16 mode is used in conjunction with an image preprocessing
algorithm to update sparse content on a white background with reduced
flash and reduced image artifacts. The GLR16 mode supports 16
graytones. If only the even pixel states are used (0, 2, 4, ... 30),
the mode will behave exactly as a traditional GL16 waveform mode. If a
separately-supplied image preprocessing algorithm is used, the
transitions invoked by the pixel states 29 and 31 are used to improve
display quality. For the AF waveform, it is assured that the GLR16
waveform data will point to the same voltage lists as the GL16 data
and does not need to be stored in a separate memory.
2.3.6 GLD16
The GLD16 mode is used in conjunction with an image preprocessing
algorithm to update sparse content on a white background with reduced
flash and reduced image artifacts. It is recommended to be used only
with the full display update. The GLD16 mode supports 16 graytones. If
only the even pixel states are used (0, 2, 4, ... 30), the mode will
behave exactly as a traditional GL16 waveform mode. If a
separately-supplied image preprocessing algorithm is used, the
transitions invoked by the pixel states 29 and 31 are used to refresh
the background with a lighter flash compared to GC16 mode following a
predetermined pixel map as encoded in the waveform file, and reduce
image artifacts even more compared to the GLR16 mode. For the AF
waveform, it is assured that the GLD16 waveform data will point to the
same voltage lists as the GL16 data and does not need to be stored in
a separate memory.
2.3.7 DU4
The DU4 is a fast update time (similar to DU), non-flashy
waveform. This mode supports transitions from any gray tone to gray
tones 1,6,11,16 represented by pixel states [0 10 20 30]. The
combination of fast update time and four gray tones make it useful for
anti-aliased text in menus. There is a moderate increase in ghosting
compared with GC16.
2.3.8 A2
The A2 mode is a fast, non-flash update mode designed for fast paging
turning or simple black/white animation. This mode supports
transitions from and to black or white only. It cannot be used to
update to any graytone other than black or white. The recommended
update sequence to transition into repeated A2 updates is shown in
Figure 1. The use of a white image in the transition from 4-bit to
1-bit images will reduce ghosting and improve image quality for A2
updates.
Figure 1 Recommended update sequence for transitioning into A2standard |
| transition |
| fast | - | drive
| <GS Image> | D → | <White> | A →
| <BW Image> | A → | <BW Image>
|
4-bit | | white image | | 1-bit | | 1-bit
|
It is also recommended to use a white image after a sequence of A2
updates as shown in Figure 2.
Figure 2 Recommended update sequence for transitioning out of A2
fast drive |
| transition |
| standard drive
|
<BW Image> | A2 → | <White> | GC16 →
| <GS Image>
|
1-bit image |
| white image |
| 4-bit image
|
2.4 Mode Version
Table 1 and Table 2 defines the mode and what mode versions available.
Table 4 lists which mode version is available for each AMEPD part number.
Table 1 Waveform Mode Summary
Mode
| Supported pixel state transitions
| Ghosting
| Typical Usage
| Typical update time at 25°C 85 Hz (ms)
|
---|
INIT
| [0 1 2 3 ... 31]→ 30
| N/A
| Display initialization
| 2,000
|
DU
| [0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 29 30 31]→ [0 30]
| Low
| Monochrome menu, text input, and touch screen/pen input
| 260
|
GC16
| [0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 29 30 31]→
[0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30]
| Very Low
| High quality images
| 450
|
GL16
| [0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 29 30 31]→
[0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30]
| Medium
| Text with white background
| 450
|
GLR16
| [0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 29 30 31]→
[0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 29 30 31]
| Low
| Text with white background
| 450
|
GLD16
| [0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 29 30 31]→
[0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 29 30 31]
| Low
| Text and graphics with white background
| 450
|
A2
| [0 29 30 31]→ [0 30]
| Medium
| Fast page flipping at reduced contrast
| 120
|
DU4
| [0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 29 30 31]→ [0 10 20 30]
| Medium
| Anti-aliased text in menus / touch and screen/pen input
| 290
|
Table 2 Mode Version Description
Offset 0x16 Value
| Offset 0x10 Value
| Mode 0
| Mode 1
| Mode 2
| Mode 3
| Mode 4
| Mode 5
| Mode 6
| Mode 7
|
0x00
| 0x19
| INIT
| DU
| GC16
| GL16
| GLR16
| GLD16
| A2
| DU4
|
3. Controller settings and manufacturing data
The information section describes the information held in the first 24
bytes of the flash file. The bytes are defined in Table 3.
Table 3 Waveform Header Information
Offset (bytes)
| Size (bytes)
| Data
| Allowed Values
| Comments
|
---|
0x00
| 4
| CHECKSUM
| 0x00000000–0xFFFFFFF
| CRC32 Checksum calculated on the entire binary data file, assuming
a value of 0x00000000 for the checksum bytes.
|
0x04
| 4
| FILE LENGTH
| 0x00000000–0xFFFFFFF
| File length in bytes (32-bit little-endian value).
|
0x08
| 4
| SERIAL #
| 0x00000000–0xFFFFFFF
| Unique 32-bit little-endian value assigned to each released
waveform file. 0x00000000 = no serial # assigned.
|
0x0C
| 1
| RUN TYPE
| 0x11–0xFF
| 8-bit value representing the type of FPL runs. R = 0x11
|
0x0D
| 1
| RESERVED
| 0x00–0xFF
| RESERVED
|
0x0E
| 2
| FPL LOT
| 0x0000–0xFFFF
| FPL lot number, (16-bit value, little-endian).
|
0x10
| 1
| MODE VERSION
| See Table 2
| See Table 2.
(Mode descriptions can be found in Table 2.)
|
0x11
| 1
| WF VERSION
| 0x00–0xFF
| Waveform version
|
0x12
| 1
| WF SUBVERSION
| 0x00–0xFF
| Waveform subversion
|
0x13
| 1
| WF TYPE
| 0x51
| Waveform type: 0x51= AF
|
0x14
| 1
| RESERVED
| 0x00–0xFF
| RESERVED
|
0x15
| 1
| AMEPD Part Number
| See Table 4
|
|
0x16
| 1
| WFM REV
| 0x00
| 0x00 = AF WFM Rev00;
|
0x17
| 1
| FRAME RATE
| 0x85
| 0x85 = 85 Hz [Field definition deprecated in 0x02 WBF Header Revision,
Do Not Use field on future designs]
|
0x18
| 1
| FRAME RATE
| 0x00–0xFF
| Frame rate converted to Hex, i.e. (0x55 = 85Hz)
|
0x19
| 1
| VCOM OFFSET
| 0x00
| 0x00 =
User should set the Vcom (VCOM(applied)) to VCOM stored in the module
flash plus the VCOM_OFFSET specified in the Voltage Control
Information(VCI).
0x01 value is reserved (for customer compatibility with the VCOM
OFFSET field)
|
0x1C
| 3
| XWIA
| 0x000000–0xFFFFFF
| Extra Waveform Information (XWI) address. The XWI contains the
waveform filename. (see Section 3.1)
|
0x1F
| 1
| CS1
| 0x00–0xFF
| Checksum of bytes 0-30 with bytes 0-7 set to 0x00.
|
0x27
| 1
| AWV
| 0x00–0xFF
| 0x00= No Advance WFM information is included; Gen I compatible
0x01= Voltage Control format V2
0x02= Algorithm Control only;
0x03= Voltage Control and Algorithm Control;
|
Log
Saturday, February 20, 2021
The two 10.3" E-Paper displays came today. Disappointing was the
fact that there was nothing in the boxes but the raw display
panels. No connectors, no documentation, nothing. Further research
turned up additional documentation web pages, and it appears that I
also need an IT8951-based driver board for each display. I ordered
the wrong item, there's another one that contains the interface too.
Oops.
Wednesday, February 24, 2021
After consultation with Waveshare, I've ordered the missing pieces,
$105 with shipping.
Tuesday, March 9, 2021
The Waveshare driver boards showed up. So, we're at about $405 so far.
Sunday, February 5, 2023
This project idea has gotten stalled. Boo. Clunkdraw has been
back-ported to C.
Return to Site Home