It’s easy to become jaded by modern microcontrollers: for just a few bucks you can get a MCU that’s powerful enough to give a desktop computer from the early 90s a run for its money while packing in contemporary technology like WiFi and Bluetooth. For many projects we don’t even have to consider optimizing our code, because we aren’t even scratching the surface of what the hardware is capable of.
But sometimes you don’t have the luxury of using the latest-and-greatest chip, and have to play the hand you’re dealt. That’s when folks like [Larry Bank] really shine. In a recent write-up, he goes over his experiments with driving e-paper displays (specifically, salvaged electronic shelf labels) with 8-bit MCUs that on paper shouldn’t have the resources to run them.
The problem is that these displays generally expect to be handed a fully-formed image, which can easily exceed the free RAM on a low-end chip. For example, a 1-bit 128 x 128 image would consume 2 KB of RAM — more than four times the available memory on an ATtiny85.
As [Larry] explains, his alternate approach is to write data to the display in columns that are only one byte wide. Combined with his existing work with image decompression on constrained hardware, he’s able to rapidly draw out full-screen TIFF images using an Arduino UNO as demonstrated in the video after the break. He hopes the work will inspire others to experiment with what’s possible using the dinky MCUs you generally find in second-hand shelf labels.
“Salvaged” shelf labels?
You mean stolen?
I’ve yet to see one of these in the wild, BTW.
Company repairs remotes containing them, get em for free en mass as they’re glued in the casing which is thrown away. Stop reading msm, people aint that bad.
The ESLs referred to in the article are more than 5 years old and were sold in large lots from stores that had closed or changed technology. Nothing was stolen.
If you’re looking for displays that are ‘new’ and might be less expensive than what I’m seeing on e-bay, some are also available on Amazon such as amazon.com/dp/B0BJ1SGSYX for a lot of 20, comes to about $19 US each. That includes the manufacturer’s hardware, so there may be other options if you can get into that, perhaps with a Zigbee solution. I can see setting up some of these on the interior of exterior doors to let people a last chance to know what the weather is before they step outside, perhaps indicate that someone is, or has been on the steps there, etc. Or just buy a lot, split it up and resell what you don’t expect to use for fun and profit.
They’re all over eBay, for instance.
What search terms do you use? I’ve tried looking and none of the ones I find seem to be a decent value when compared to dev boards
Here’s an example listing; €2 each is hard to beat:
https://www.ebay.de/itm/175487104862
Another, cheaper, example on Ebay UK: https://www.ebay.co.uk/itm/234788031136
Those aren’t e-ink. ZBD invented a bistable LCD. They are similarly slow to update, but have lower contrast and non-standard connector/signals.
Hey guys, try to include the title of the item when posting links like this. Otherwise the information is lost when the listing expires and the wayback machine doesn’t seem to have it
They are from a store called Metro. It is the German version of Sams Club.
They’re kind of like write-only memory, when you think about it.
You can read them too! (With your eyes)
I’ve written similar libraries to interface atmega328p’s to larger higher resolution epd’s writing bitmaps stored in flash to the display. I made a desktop epd clock/calendar that runs a 4″ display at 300×400 pixels off a 328p, storing higher resolution fonts in flash using progmem. The stock libraries provided by epd manufacturers that rely on double buffering from ram just cant even hope to run on mcu’s with only a few KB of ram (especially when you get into the “3” color displays). Doing things like image rotation, scaling or mirroring requires trading cpu cycles for memory but is possible even with dinky chips.
Thanks to the author for reminding us how to get more from less. This reminds me of old 80×24 terminals which used a single byte of RAM per character, repetitively converting ASCII to pixels on the fly via a “fast” character-generator ROM driving the video = 1920 bytes per screen[1].
Neopixel/WS2812 libraries also often use the naive approach, which is to allocate 3 bytes (R, G, B) per LED, limiting CPUs like the ATTiny85 to barely 85.
As long as the CPU can keep up with the WS2812 timing, it may be better to /compute/ the color on the fly.
For Neopixel displays which only use a few colors, a color map saves memory. A VU meter for example might only have 4 colors: off, green, yellow, and red; requiring 4colors x 3(RGB)=12 bytes, allowing the ATTiny85 to drive over 200 LEDs storing one byte per pixel (which is a waste since only 2 bits are necessary, but the library code’s easy and flexible). If the color map’s known at compile time, it can be compiled into program memory, saving precious RAM for other things like more pixels. The ATTiny85’s plenty fast enough to do the color lookup while programming pixels[2]
Custom things like bar graphs can use even less memory. Imagine a 1024-pixel WS2812 string used to display a 10-bit value from an A/D converter as a red bar graph. The neopixel driver simply loops 1024 times and programs each pixel either red or off, on the fly. 1024 pixels using around 8 bytes of RAM (the colors and loop+comparison are in program memory).
[1] With video attributes (reverse, blink, underline, bold) and often a 25th text line, RAM was often a bit higher than 1920 bytes
[2] It’s easier to do this if the super-restrictive idea of WS2812 time is relaxed aka http://wp.josh.com/2014/05/11/ws2812-neopixels-made-easy/ with which I’ve had good success
Busted link :-( Try https://wp.josh.com/2014/05/13/ws2812-neopixels-are-not-so-finicky-once-you-get-to-know-them/
Can do vector graphics a line at a time on an atmega328p no problem. Vector graphics can be smaller than bitmapped for certain designs. To render, only need enough memory to store a list of edges intersecting the current line, then render the line after sorting the edges. 2k is more than plenty of memory to do that.
reminds me of trying to cram gifs on 3.5″ floppys
G3 Fax compression is also a reasonable choice, if you can do the bit-twiddling compactly enough; old-style fax machines didn’t have a lot of CPU horsepower.
I had to do something similar to run more than 83 NeoPixels from an ATTINY85. Almost all the existing Arduino libraries expect you to hold a copy of the bitmap in memory, make your modifications to the bitmap, then dump that bitmap to the pixels. But 83 pixels * 3 bytes = 249 bytes, and there’s only 512 bytes available on an ATTINY85. And if you want to do animation, you’re having to scroll through the entire array doing memory copies the whole way down.
Starting from a library written by John ‘bigjosh’ Levine, that directly twiddled bits, I set up a 1D array of bytes that I could programmatically convert to the 3 RGB bytes on the fly. You had to do the conversion quickly, because you only had a few cycles between each LED in the NeoPixel protocol, but it ended up working perfectly for me!
Animation — especially shifting — was especially easy. You could choose anywhere in the array to start, then step in either direction and whatever rate you desired.
I ended up using a full byte when I only actually needed 1 bit for my use case, but I imagine one could easily come up with a packed-byte format to add colors, or even a GIF-style palate that you could rotate.
I owe a debt of gratitude to the writers of NeoPixel drivers, but there are sometimes when twiddling bits is your best — any maybe only — option.