From 02000daaa6b1eb608c008a784b51067c65da1305 Mon Sep 17 00:00:00 2001 From: uvok Date: Thu, 7 Aug 2025 16:52:14 +0200 Subject: Continue epaper --- _drafts/building-an-epaper-badge.md | 143 +++++++++++++++++++++++++++++++----- 1 file changed, 124 insertions(+), 19 deletions(-) (limited to '_drafts/building-an-epaper-badge.md') diff --git a/_drafts/building-an-epaper-badge.md b/_drafts/building-an-epaper-badge.md index 86fea3e..8197d25 100644 --- a/_drafts/building-an-epaper-badge.md +++ b/_drafts/building-an-epaper-badge.md @@ -14,36 +14,141 @@ Two weeks before [{% post_url 2025-07-30-awoostria-con-report %}](Awoostria): So it begins… The story how I build myself an ePaper badge. -## Requirements +Actually, the story begins way earlier, when I still had a physical Raspberry Pi +running stuff in my home network, and I wanted to tinker around a bit, and +bought myself a Waveshare ePaper. These simple black-and-white displays which +maintain their content when the power goes off, which is also inside eBook +readers. -Actually, the story begins way earlier, when I still had a physical -Raspberry Pi running stuff in my home network, and I wanted to tinker -around a bit, and bought myself a Waveshare ePaper. These simple -black-and-white displays which maintain their content when the -power goes off, which is also inside eBook readers. +Some years ago I wanted to build myself a doorsign for the EAST convention, and +I wanted to go "as minimal as possible". I wanted to use one of the MSP430 +controllers I had laying around, and I wanted to switch motives via MiFare RFID +transponders (using an MFRC5xx reader). Work on that development never really +took off. -Some years ago I wanted to build myself a doorsign for the EAST convention, -and I wanted to go "as minimal as possible". I wanted to use one of -the MSP430 controllers I had laying around, and I wanted to switch -motives via MiFare RFID transponders (using an MFRC5xx reader). -Work on that development never really took off. +## Requirements -So this time, I simply said "fuck it", and threw an ESP32 on the problem, -and decided to use [PlatformIO](https://platformio.org/), a -toolchain/SDK/library manager. I started with the Arduino framework, -which is… pretty wasteful in terms of resources (Flash/RAM/…), -but speeds up development significantly. +So this time, I simply said "fuck it", and threw an ESP32 on the problem. +Also, I decided to use [PlatformIO](https://platformio.org/), a +toolchain/SDK/library manager. I started with the Arduino framework, which is… +pretty wasteful in terms of resources (Flash/RAM/…), but speeds up development +significantly. -I had a simple ESP32 devboard, and one of the Waveshare modules, -and started coding. +I had a simple ESP32 devboard, and one of the Waveshare modules, and started +coding. … -But wait, what to I even want to achieve? +But wait, what to I even want to achieve? Well, I wanted to "mood badge", i.e. +show my current mood with funny pictures. I couldn't get one on previous +conventions, so I was just gonna build one myself. + +This involves several sub-problems: + +* Control the ePaper display +* Get the pictures on the display +* Set what is displayed +* Power-saving +* Attach the badge to myself + +## Control the display + +Usually, you never talk to the displays themselves, but to a display +controller. Usually, you talk to these via a digital interface, e.g. +SPI. There are different display controllers with different command sets. + +But why bother with implementing this myself? There are ready-made libraries. +For myself, I decided to use [GxEPD2](https://github.com/ZinggJM/GxEPD2). +They support *some* Waveshare displays. The problem with Waveshare displays is, +they don't disclose which display controller they use. So it's kind of an +trial-or-error procedure. Or rather, you can look at their example code, +figure out which commands they are using, and compare what commands +GxEPD2 uses. That's a but cumbersome. + +## Get the picture on the display + +You can't just simply throw a jpeg onto the display. a) The display doesn't +understand that. It only understands pixel data. (the library doesn't, +either). b) The display can only draw black and white pixels. + +So, you definitely can't throw a color picture on the display, not a monochrome +one. There are displays which support a few gray-levels, though. + +So. What to? The solution is "dithering". I.e. you trick your eye into +perceiving grey by having clusters of black and white pixels. There is some +background to dithering, but I simply used either GIMP, the Floyd-something +algorithm, or one of the "ordered" modes of ImageMagick. + +This, then, looks like this: a dithered image of my fursona + +TODO: XBM + +## How to attach the badge to myself + +This would be cumbersome. I had a Waveshare module/PiHat (to heavy), and a +simple "ePaper sheet" - which would be too cumbersome to attach to the +devboard. So, at this point, I decided to switch from the prototyping platform +onto something better. + +Fortunately, Elecrow provides a +[CrowPanel](https://www.elecrow.com/crowpanel-esp32-2-9-e-paper-hmi-display-with-128-296-resolution-black-white-color-driven-by-spi-interface.html), +which is exactly what I need. It has a display, a built-in ESP32, a housing, +and even some switches! + +I decided to glue magnets onto the housing, and attach the display +via magnets on the inner side of my shirt - not ideal. I positioned the +magnets in the (vertical) middle of the housing, so it wobbles and is not +readable. Also, I accidentally washed the shirt after Awoostria with the magnets +still sticking inside - and now there's a hole in it. :( + +## Set what is displayed + +In addition to these controls, which allow choosing the motive, I wanted +something "more direct", so I added the +[NimBLE-Arduino](https://github.com/h2zero/NimBLE-Arduino) library. With a bit +of coding, the available presets/motives could be read via BLE, +and also one could be selected via another characteristic. + +Actually, the switch-selection was a but troublesome. +Redrawing the whole display takes around 2 seconds - but that is +not acceptable when navigating the presets one-by-one. +By looking at the API, I found out you can select a "partial region". + +What I didn't mention yet, the text that shows the mood is drawn using +the API - not integrated into the picture. So, I simply update a +region in the vertical-center-right of the display with the mood text. +The selection is confirmed my pressing the rotary switch. + +This is still not ideal. The first update must be a full-one, +and I don't save the selected preset in NVS - I don't want to destroy +the flash by hundreds/thousands of write cycles. I don't have a solution +to this, yet. Maybe I'm gonna integrate an microSD card (there's a slot for that!). +Gonna research a good wear-levelling file system for that. Probably not FAT. That doesn't +need to be readable on the PC. (And even if, simple stuff can be written in FUSE). + +## Power saving + +I first measured the current and was shocked. The whole thing +draws around 80-100 mA. Not a big surprise, given that Arduino +basically calls `loop()` over and over again. + +Using a bit of experimenting, and failing to cancel light sleep with +an GPIO interrupt, I implemented power saving by using a timer-based +light sleep (10 ms, gives good user response) and reducing the CPU frquency to +TODO????? MHz. + +And lo and behold, my USB current measuring equipment (resolution 10mA) showed 0 mA. Success. + +Actually, reducing the CPU frequency was a requirement! If I didn't do that, +the CPU would constantly crash when entering or exiting light sleep. No idea why! + ## Resources + +bla on dithering bla. + -- cgit v1.2.3