Thanks @marcmerlin for pointing out this alternative library. I think it’s a good choice for ESP32 projects that need to be RAM efficient, or drive high pixel counts at the cost of graphic quality.
I posted this as a comment here, but I’m reposting here as well (“you”/“your”/etc is referring to the author): https://github.com/mrfaptastic/ESP32-RGB64x32MatrixPanel-I2S-DMA/issues/7#issuecomment-678489850
Cool to see that there’s another library option for people wanting to drive HUB75 panels with an ESP32. It looks like we’re going after different goals with just a little bit of overlap. SmartMatrix Library supports minimum 24-bit refresh, ESP32-RGB64x32MatrixPanel-I2S-DMA supports maximum 24-bit refresh. I’m focusing on visual quality over max pixel count, so my library is optimized for that. I do plan on making this more clear in my documentation (which really needs a refresh, I’m just starting to move it to a GitHub Wiki from an unmaintained website), and I’ll steer people to this library and the RPi library for those that need higher pixel count than SmartMatrix Library can handle.
I took a quick look under the hood here to see how memory is being used more efficiently. Here’s some of the differences I spotted, and please correct me if I got any of this wrong:
- Double buffering in the I2S buffer is disabled by default, and it looks like most of your examples don’t use it, saving a bunch of DMA RAM. Are you doing anything to avoid visible tearing or glitching when the I2S buffer gets updated with new content at the same time it’s being refreshed to the panel?
- You’ll also save half the DMA Linked List Descriptors which can be large
- (You could save even more RAM by using an external latch to store the address like SmartMatrix Library optionally does)
- When drawing a pixel, you can draw directly to the I2S buffer, avoiding any intermediate buffers.
- What happens if drawing graphics is slower than the refresh rate, doesn’t it result in tearing as some of the new pixels are refreshed on one frame, and some on the next?
- You also can’t currently read the color of a pixel you’ve drawn to the buffer, but a lot of time that functionality isn’t used.
- I think a good test case for this is to sweep a vertical line (or scroll text) horizontally quickly across the screen, so there’s pixels on each row. I tried to save RAM in a project I was working on using SmartMatrix Library and removed the double buffering and the tearing showed up with scrolling text and I had to save RAM another way.
- You do use Adafruit_GFX which uses uint16_t to store pixels, and has double buffering. That saves 1/3 of the RAM compared to SmartMatrix Library’s minimum 24-bit drawing buffer. I believe the Adafruit_GFX buffers are optional, so you can save a ton of RAM if a sketch like AuroraDemo is only drawing directly to the I2S Buffer and not using Adafruit_GFX.
So, compared to SmartMatrix Library, I believe the big savings are: half the I2S DMA Buffer and linked list descriptors, and either no intermediate drawing buffers, or if there are buffers, they’re 2/3 the size.
I don’t think it would hurt to have an option in SmartMatrix Library to disable the double buffering, but I’d leave double buffering on by default. Drawing directly to the I2S buffers is a fundamental change that breaks how SmartMatrix Library is designed, with independent layers that have their own buffers, and a separation between the drawing and refresh memory.
I do like the idea of using Adafruit_GFX as a layer in SmartMatrix Library for those that want to use the Adafruit_GFX drawing routines to save RAM or for sketch compatibility. I wish they had up to 24-bit color support. Their font support has improved dramatically since I last looked at it (SmartMatrix Library used to be better), so it would be nice for people that need better fonts to have access to them.
I also like your idea of taking some patterns from Aurora and turning them into an easy to understand sketch. I’m going to have to add that to a SmartMatrix Library example.