Help with the custom LED display

Status
Not open for further replies.

MrBee

New member
Hello,

Im currently working on a custom LED display that is irregular in shape. The display is made of ws2812-2020 LED strips to form one big display. On this display, I want to display video animations in .mp4, .mov, or any video format. My current setup for that Is a Teensy 4.1 which has then 40 pins connected to a datapad on each LED strip. I have followed a guide on PRJC website for the OctoWS2811 library which I end up using in the code (https://www.pjrc.com/teensy/td_libs_OctoWS2811.html). I am also using a 74HCT245 buffer chip and I converted a video to a .bin format with Processing as instructed. However, the video does not play properly on the display at all, so im reaching out to you to ask if you can maybe point me in the right direction or maybe know any company that might assist or takes over that project. Basically, any information would be super helpful.

I have already checked the forums but I can't seem to find any thread that addresses my issue.

If you require more information about it I'll be happy to provide

Thank you in advance,
Miha
 
You have basically 2 choices. You need to somehow map the original video pixels onto your irregular shape pixels.

Most people would do this on the PC side. You would to need to modify movie2sdcard.pde, so it put only the pixels you actually use into the binary file.

You other option would be the send all the original pixels into the file, and then have code on the Teensy side which copies only some of them to OctoWS2811's drawing buffer.


As a very first step, you'll probably want to simplify the image2data() function starting at line 108. It transposes all the bits into the format required on Teensy 3.x. Than in the VideoDisplay_Teensy4.ino example, the copyIncomingToDrawing() function starting at line 255 converts the transposed data back to ordinary RGB pixels. This bit transpose is very difficult to visualize, and it's completely unnecessary on Teensy 4.

Your new image2data function would probably look something like this.

Code:
void image2data(PImage image, byte[] data, boolean layout) {
  int offset = 5;
  int x, y;

  for (y = 0; y < image.height; y++) {
    for (x = 0; x < image.width; x++) {
      int c = image.pixels[y * image.width + x];
      int red = (c & 0xFF0000) >> 16;
      int green = (c & 0x00FF00) >> 8;
      int blue = (c & 0x0000FF);
      red = gammatable[red];
      green = gammatable[green];
      blue = gammatable[blue];
      data[offset++] = red;
      data[offset++] = green;
      data[offset++] = blue;
    }
  }
}

Hopefully you can understand how this is just scanning through all the image pixels and copying 3 bytes into the output data. Simple, right? (it might have minor errors... I just typed it now, didn't actually run it in Processing)

Before you dive deeper, I'd highly recommend getting this working so you don't have that brain-twisting bit transpose as a huge distraction.
 
Now, looking at your picture and focusing only the right hand side where the LEDs are lit up, it looks like the widest part is about 60 pixels and I counted 42 rows. So in that Processing code, you'd set the video scaling to 60 by 42.

image.jpg

But you don't have all 2520 pixels. You will need to edit the Processing code so it doesn't copy some pixels to the data[] array.

You don't need to create beautiful or concise code, since it only runs once on your PC. So I'd suggest keeping it simple, even if that means a lot of extra lines. For example, if that first row is 40 LEDs, you might do something like this:

Code:
  for (y = 0; y < image.height; y++) {
    for (x = 0; x < image.width; x++) {
      if (y == 0 && x >= 40) continue;
      int c = image.pixels[y * image.width + x];

This will cause the Processing code to just skip running the rest of the loop for the last 20 pixels in the first row. The 2nd row look like it has 6 more, so maybe you'd add this:

Code:
  for (y = 0; y < image.height; y++) {
    for (x = 0; x < image.width; x++) {
      if (y == 0 && x >= 40) continue;
      if (y == 1 && x >= 46) continue;
      int c = image.pixels[y * image.width + x];

Some of your rows don't start at the beginning of the picture. So maybe you'd add this.

Code:
      if (y == 23 && x < 6) continue;
      if (y == 23 && x >= 56) continue;

If you end up writing 60-some lines for all the cases but it works, call it good and don't worry about trying to craft some sort of "elegant" programming that uses a small number of lines with complex code. Simple but long is more typing but probably all you need here.

On the Teensy side, if the binary file has only the LEDs you need, then you can just copy the data into the OctoWS2811 buffer and display it. Easy, right?

Well, there are some other details. The main issue is if your LED strips are arranged in a zig-zag format, then you need to reverse the pixels in every other row. You can see the original code did that with this:

Code:
    if ((y & 1) == (layout ? 0 : 1)) {
      // even numbered rows are left to right
      xbegin = 0;
      xend = image.width;
      xinc = 1;
    } else {
      // odd numbered rows are right to left
      xbegin = image.width - 1;
      xend = -1;
      xinc = -1;
    }

One way or another, you need to get exactly the right number of pixels into the OctoWS2811 drawing buffer and in the right order.

The other way would look pretty much the same, except you read all of the original 2520 pixels from the binary file and then code on the Teensy side selectively copies only some of them in the drawing buffer. It really doesn't matter much if you do that work once on your PC or if Teensy does it for every video frame. Either way, the path to success is keeping things simple. Writing a lot of if checks on x,y coordinates may be a lot of typing, but it's simple and you can run it to check if the first line is displaying properly before adding the 2nd line, and so on until you get the whole thing the way you want.
 
The issue I see from the videos seems to involve speckling and artifacts that might be to do with
the colour mapping, doesn't seem to be just shape issues. It also might not be resampling suitable
to the resolution needed by the display, meaning its zoomed in too much on details and thus showing
the noise more?
 
Thank you so much for the detailed explanation. The display is basically made from left and right side. From each side LED strips run to the middle where strips meet but they are not connected. I will try to modify the files you said and get back with the results. However i suspect that the issue is with scaling or encoding of the video file.

Thank you to be both of you for now.
 
Status
Not open for further replies.
Back
Top