Simple test program for a Waveshare Tri-Color 1.54 Inch E-Ink Display Module connected to a Wemos S2 mini board (ESP32-S2 based with USB-CDC).
Actually, I would love to implement this using ESPHome to easily embedd it into my HomeAssistant-instance, but support for E-Ink displays is rather limited. Note, never buy before reading...
This project is implemented using PlatformIO with the arduino-3 platform from the (p)eople (i)nitiated (o)ptimized (arduino) (pioarduino). For my convenience, OTA-programming is enabled by including the ArduinoOTA-library from Espressif Systems' Arduino ESP32 project.
Firmware updates and ArduinoOTA is enabled with a small safeboot partition (640KB). The main app can span over ~3MB. To trigger a restart into this partion, just call http://epaperthingy.local/safeboot
or hit the SafeBoot-button in the Settings-page. After a few seconds the OTA-Website shows up:
A little quirky, but the safeboot-partition is tapping the preferences of the main app to connect to your WiFi, or will create a softAP (in this case you might even upload new firmware from the captive portal after connecting to it - tested only on mac though).
When using Over-the-Air (OTA) updating from PlatformIO, the safeboot-mode will be activated via a script when you hit Upload (see extra_scripts = tools/safeboot_activate.py
).
- The webserver is powered by ESPAsyncWebServer - GNU Lesser General Public License v3.0
- The network manager is MycilaESPConnect - GNU General Public License v3.0
- The task manager is TaskScheduler - BSD 3-Clause "New" or "Revised" License
- The library to control the E-Ink display is GxEPD2 - GNU General Public License v3.0
- The safeboot-partition contains ArduinoOTA and OTA-Update - the scripts factory.py and safeboot.py from MycilaSafeBoot fall under MIT license. ArduinoOTA and Update are from Espressif Systems' Arduino ESP32 core library. Both are Apache-2.0
- The icons from the Mono Interface Icons Collection are public domain
After connecting a display to your board, compile the project, flash it to your board. Connect to the new Access-Point (ePaperPortal) and connect the board to your trusted WiFi. Afterward you can just open http://epaperthingy.local
to see the (minimalistic, at most...) Website.
Test pictures are shown on the display when clicking the image area.
The GxEPD2-library is quite easy to use, yet it is blocking. As the display takes ages (~ 15 seconds) to show something new, I sprinkled in some preemptive tasks (FreeRTOS) that are hidden in cooperative tasks (TaskScheduler) and thus use the same simple interface for signaling the status.
Flashing the board for the first time (with the factory.bin, which is including SafeBoot, the application and the files system image) is done via esptool within PlatformIO to the USB-CDC of the Wemos S2 mini board. Remember, when using a board with USB-CDC, you need to press both buttons, release the "0"-button first, then the "RST"-button (this sequence will enable the USB-CDC). Subsequently, you can just flash it without button juggling or simply flash it OTA (set upload_protocol = espota
and upload_port = epaperthingy.local
, and also add extra_scripts = tools/safeboot_activate.py
in your platformio.ini). Additionally, you can use SafeBoot (hit the SafeBoot-button in Settings) to upload firmware and file system images.
When flashing the factory.bin (e.g. after updating SafeBoot) you'll always have to to the button juggling.
That's up to you! Implement your idea on how to use this project to get something interesting done. For me, it's a template to implment a small button with a display that's indicating the state of my smartlock and will open/close it with a push of a button (as I'm too lazy to rotate the knob myself). Yet, this relies on my HomeAssistant instance...
Just fork the git! Some points that I would have liked to know earlier:
- The favicon was prepared using Favicon generator. For real. The icon that I use is from the Pictogrammers' Material Design Icon Libray and was designed by Simran.
- See the
WebServerTask.cpp
on how to serve the logo for ESPConnect. - The favicon-images are taken from the data-folder, compressed and linked into the firmware image. When you want to find out how to use them, have a look in the
firmware.map
(in.pio/build/[your-env]
). - This project is using TaskScheduler for cooperative multitasking. The
main.cpp
seems rather empty, everything that's interesting is happening in the individual tasks. - Creating svgs with Inkscape leaves a lot of clutter in the file, SVGminify.com helps
- jsfiddle in extremely helpful in testing the websites. See one of the test fiddles here
- You can burn your time easily when trying to come up with solutions for marginal problems...
Images for Waveshare Tri-Color 1.54 Inch E-Ink Display Module are written as pixel data bitmaps indepentendly for black and red pixels.
Waveshare is giving a brief guide on how to prepare images for their Black/Red ePaper-Panels using Floyd-Steinberg dithering, which is using a color map being read by Photoshop to convert the image, export a gif and finally convert to bitmap using another software.
The process is rather clumsy and uses costly software for a simple task that can easily be replaced by a few lines of python code.
Some StackExchange-Thread way from the past is giving a hint on how to read .act-files according to Adobe's description using python:
import struct
actColors = []
with open("./assets/Black-White-Red.act", "rb") as actFile:
for _ in range(256):
raw = actFile.read(3)
color = struct.unpack("3B", raw)
actColors.append(color)
# get and print unique entries
actColors = list(set(actColors))
print("\nColors in .act:")
for col in actColors:
print(col)
The Black-White-Red.act
file from Waveshare contain just three (unique) colors:
- [0,0,0]
- [255,0,0]
- [255,255,255]
As the Black-White-Red.act defines just 3 colors - black (0,0,0), red(255,0,0) and white (255,255,255), there is no need to read the act-file for the actual conversion. A palette for conversion is created on the fly.
The script svg2rbmono.py
that is executed during platformIO's build-process creates two 1-bit bitmap images from an svg input file automatically: one for the black pixels and one for the red pixels. The bmp-files are placed alongside the svg in the data-folder that is used to create the littleFS image. No need for manual conversion...