DIY POV Display 131*131 12bit Color  - Page 1
Forum section: electronics / general

author: pknoe3lh
author_rank: Regular Contributor
timestamp: October 01, 2019, 01:45:26 pm
content: HelloI spend a lot of time in documenting the building process of my POV Display. I also optimized it to be easier to rebuild.HF:https://www.instructables.com/id/One-POV-Display-to-Rule-Them-All/greetingsPatrick

author: ledtester
author_rank: Super Contributor
timestamp: October 01, 2019, 05:59:18 pm
content: One of the trickiest problems to solve in creating a POV display is transmitting power to the rotating electronics. Do you have any details on how you solved that?

author: mariush
author_rank: Super Contributor
timestamp: October 01, 2019, 07:23:54 pm
content: Surely you can do this without resorting to fpgasThere's proper LEDs in packages with less plastic, that would allow you to place the leds packed tigher together , for example something like this:https://www.tme.eu/en/details/rf-w2s155ts-a41/smd-colour-leds/refond/You can get 100 for 9$ ... adafruit sells 5m (300 leds) for 90$. even when you factor in the price for the led drivers you're looking at much cheaper price.There's led drivers that can control 32 leds at a time, so you could have one led driver per group of 8 leds.ex. 3.8$ / 50pcs TLC5954RTQR (48 channels grouped in 16 x R,G,B)https://www.digikey.com/product-detail/en/texas-instruments/TLC5954RTQR/296-40587-1-ND/5178464Going with 128 leds, you'd need 8 such chips, so 30$ ... 40$ including the leds. For 300 leds, you'd need 72$ worth of drivers (19pcs) and 30$ worth of leds .. so around 10$ more expensive.But at least the drivers can run at up to 30Mhz and you can pack the leds closer together.1.9$ / 50pcs IS31FL3236-TQLS2 (36 channels, 12 leds x RGB)https://www.digikey.com/product-detail/en/issi-integrated-silicon-solution-inc/IS31FL3236-TQLS2/706-1361-ND/5319752For 132 leds, you'd need 11 of these, so a cost of ~25$ .. they use i2c though, with max 4 devices per i2c, so you'd need something with at least 2 i2c outputs.or you can hit lcsc and get 16 channel shift register drivers for 5-10 cents each :https://lcsc.com/product-detail/LED-Drivers_Shenzhen-Sunmoon-Micro-SM16106SC_C121618.htmlhttps://lcsc.com/product-detail/Others_MBI-MBI5124GM_C261131.html

author: pknoe3lh
author_rank: Regular Contributor
timestamp: October 02, 2019, 09:01:52 am
content: Quote from: ledtester on October 01, 2019, 05:59:18 pmSee attachment ;-) The Rotating Part needs around 30W => 12V and 2.5A therefor you need a solution with very low resistance. I use barrings dismantled for the rings and Cole brushes from an DC motor.Quote from: mariush on October 01, 2019, 07:23:54 pmNo I can not ... Do you?There is a lot of going an. Frame buffer is ~25kBThe leds needed to be updated. the most outer led ~10k a second. (131*pi*24). For an update yo need to send 4 BytesSo I have 4 Groups:1: 9.8k updates x 5 leds => 235kB/s ~ 2Mbit/s2: 8.4k updates x 6 leds => 235kB/s ~ 2Mbit/s3: 6.6k updates x 8 leds => 216kB/s ~ 2Mbit/s4: 4.1k updates x 13 leds => 230kB/s ~ 2Mbit/sThe leds can go up to 10Mbits but there you will get reliability problems ...A total of 1MB/s for one wing => 4MB/s for all 4 WingsYou also need to calculate the position of the LEDs => sin and cos. There are symmetries and optimization you can do.Then we need 4*4*2 => 32 IOs and preferential 16 SPI maters in hardware. Or Use an extender ...The problem is that I cannot easily check If it will work. Thats why Im using an FPGA => there I Know I will get it to work.Quote from: mariush on October 01, 2019, 07:23:54 pmThe idea was to make it reproducible without SMT components ... for beginners.Quote from: mariush on October 01, 2019, 07:23:54 pmIf I would build an POV again for myself (I did allready:https://im-pro.at/index.php/projekte/2018-pov) I would for sure look closer at you suggestions ;-)

author: mariush
author_rank: Super Contributor
timestamp: October 02, 2019, 09:30:38 pm
content: I gave this some more thoughts.Here's my thinking.Do everything in multiples of 8. This would allow usage of bit shifting to speed things up or quickly look up data in memory.Therefore, let's say we go with a 256x256 square for the image and so, you'd use 256 leds for the diameter of the circle.If you imagine the square image segmented in 8x8 pixel blocks, a 256x256 pixel image would have 1024 blocks, but only 856 8x8 blocks will ever need to hold the viewable data.For a 8 bit color (or grayscale) image, out of 64KB, just ~54 KB would be visible content, so the rest of ~ 11 KB can be used to cache some things (lookup tables, precalculated data etc)For this reason, and to simplify the code, it's important to have a 256x256 byte array to hold the picture.For grayscale images, each byte would hold the luminance of the pixel.For 256 color images, each byte holds the color index from the color palette - you'd need 256x[12..24 bits] for the color palette which could be stored somewhere (6-12 blocks of 8x8 pixels that are unused in the picture)For 12-16 bit color, you'd need to use a second 256x256 array.Now, simply determine how precise you want to be. You could have as little as 360 steps, or you could do things in 0.5 degrees (720 updates per rotation) or 0.25 degrees (1440 updates per rotation).It will probably be enough to do 720.Now, at every 5 degrees or 10 degrees step, I'd precalculate the 128 points (x,y) the leds would display... again this is where using maximum 256x256 image and using 128 and 256 helps.This means I'd have at worst case scenario 256 bytes per pre-calculated line of 128 leds, but we can probably use compression, as in store the coordinates of the first pixel and then you know it's unlikely the next pixel is gonna be more than 2-3 pixels up or down, so you could use a single byte for each (x,y) - [-3..4] (4 bits) for x, [-3..4] (4 bits) for y ... so at most 129 bytes used for each line.If we go with 5 degree steps, that means 72 such lines, so we'd need 72 x 128 bytes = 144 8x8 blocks + 2 blocks for those 1 byte over the 128 bytes used by each line. .... basically 146 blocks.We had 1024 blocks of 8x8 at start, 856 blocks had usable image, so we had 168 blocks free.If 12 blocks are used for palette information, you're left with 156 blocks free. 146 of these can be used to hold these pre-calculated lines at every 5 degrees.What's the point of these? Well, these are kind of like checkpoints, or like restart points.There's gonna be a function or something that works in background starting from one of these steps and calculates the values for the next steps, ex start from 5 degrees and calculate 5.5, 6, 6.5...all the way up to 9.5If there's some speed fluctuation or something and suddenly you need to draw 11 degrees but you were still working at 5..9.5, you can reset and start working from 15 to 19.5 and for a small part of the rotation you'll have bad data.If there's enough memory it could be possible to not even calculate, just precompute everything. For each led, just store how much the coordinates of each point change (ex y increased by 1, x decreased by 2) from previous line... so you could use 4 bits per led... with 128 leds you're looking at 64 bytes without any sort of RLE compression.

author: pknoe3lh
author_rank: Regular Contributor
timestamp: October 03, 2019, 08:53:20 am
content: Quote from: mariush on October 02, 2019, 09:30:38 pmOK I can follow you so fare! when you have 256 x 256 pixel the circumference for the most outer pixel is ~800 pixel => 720 should be enough!Quote from: mariush on October 02, 2019, 09:30:38 pmPrecompute Positions: Worst case: 256 Leds * 720 Updates * 2 Bytes coordinates => ~350KB There are a lot micro controllers that can handle that ;-)We can also buffer an update or even multiple => 4Bytes + 265 Leds * 4Bytes => only 1KbytesWith hardware SPIs and DMA we can stream them in the background. If we have enough or we use high speed LED driversBUT we need to calculate 720*24 updates per second => ~17k/s to calculate the updates we need to access 1k Buffer + 256*2 addresses + 256*3 (RGB or color Table) random access to the frame buffer (not really cached)This gives us a memory load of: 17k * (1k+2*256+3*256) => ~40MB a second and in parallel still the DMA operation (~17MB/s) for the SPI hardware.Thats a lot even for A high end micro controller ...Next You will invest a lot of time get that implemented and tested just to find out that there is something in the architecture you overlooked that is an bottleneck ....

author: mariush
author_rank: Super Contributor
timestamp: October 03, 2019, 11:04:28 am
content: No, your picture is 256 x 256 ... so 256 leds for the diameter :there's 2-3$ ARM based microcontrollers with 256-512 KB of SRAM, plenty to hold everything in ram.ex : 2$ (25pcs) for ARM Cortex M4 running at up to 100 Mhz with 1MB of ram :https://www.digikey.com/product-detail/en/microchip-technology/ATSAM4N16BA-MUR/1611-ATSAM4N16BA-MURCT-ND/68326016$ (25pcs) for 256KB ram and 180 Mhz STM32F446RCT6 :https://www.digikey.com/product-detail/en/stmicroelectronics/STM32F446RCT6/497-17472-ND/7650386Re memory bandwidth: You could use multiple microcontrollers, for example one for each 128 led segment (if you make a cross out of 4 x 128 led segments). It could be a tad more complex to sync all four - the easiest would be to just go overboard and have 4 micros and 10 wires to each micro: 9 for angle data (0..360) and 1 for strobe/enable (signal micros at same time to change angle)... 11 wires if you want half degree precisionAlso no, you're not reading 3 bytes per pixel, you're reading 1 or 2 bytes per pixel (256 color palette, 444 or 565/whatever in worst case scenario). You don't have leds precise enough and powerful enough to have 256 light intensity levels for each color of a led anyway. Dither the image down to 565 or 444 or something like that.If you use 256 color (1 byte per pixel), your ram bandwidth is a bit higher than using 2 byte per color all the time but you save ram.ex for 128 led segment 256 color palette: read the coordinates of each point (66 bytes) + read the color index for each (128 bytes) + [1..128 x 2 bytes] = 322...450 bytes per segment. For a full rotation, you have up to 450x360 = 162,000 bytes per frame if you go with 320 updates per turn, 324,000 bytes for 720 updates per turn. For 24 frames, you'd have 3,888,000 bytes or 7,776,000 bytes a second.If you use 10/12/16 bit color per pixel you can just have two 256x256 arrays and read 2 bytes per pixel.. so now you read 66 bytes for the coordinates of each point, then read 2 bytes x 128 bytes ... you have 322 bytes per angle. That's 115,920 bytes for a 360 step rotation, or 231,840 for 720 updates each rotation.This version uses less bandwidth as you can see, but the memory needed is double (2 x 64 KB + potentially extra stuff). If you're ram size constrained, palette makes sense.Just had some fun in php calculating the coordinates of the pixels on each line so you can see how compressible it would be using RLE encodingIf you check the txt file attached, you can see it would compress quite well.Also added the php script I used (open it in any text editor or run it with php.exe script.php >text_dump.txt - and note it will try to save the generated png file in c:\temp\ - you'll get error if folder doesn't exist)ps. you could also have a sort of hybrid ... one pixel wide line for the stuff near the center, and 2 pixel line for the 48-64...128 range, where there would be some gaps as you can see in the imageps i think my math is a bit wrong... it would be one byte for each of the 127 leds that follow the first, which has known coordinates ... so 127 bytes instead of 66 bytes. Worst case scenario. Can be much less using RLE compressionedit: a very basic rle encoding would reduce the 360 angles to 30166 bytes or avg of 83 bytes per line... see script and txt attached.edit2: and actually, you only need to store one 90 degree chunk, the coordinates are the same for the other 3 chunks of the circle, just flipped or mirrored (ex decrease x offset instead of increase etc etc) ... 1/4th of 30KB (rle compressed) or around 8 KB would be enough

author: pknoe3lh
author_rank: Regular Contributor
timestamp: October 03, 2019, 11:38:41 am
content: Wow. You pulled that up quickly ;-)I did not say its impossible ... I was just afraid that I would spend a lot of time implementing and then find out that its not possible.I would be genius if we could run this on en ESP32 with WIFI active. Maybe just 64x64 and sell it as a helmet ()

author: thm_w
author_rank: Super Contributor
timestamp: October 12, 2019, 12:30:03 am
content: Quote from: mariush on October 03, 2019, 11:04:28 amLooks like the first one has 1MB of flash and 80kB of ram.Second is 256/512kB flash, 128kB of ram.