Optimization for LED project

Soulthought's icon

Hello everyone,

I'm currently working on a patch for a LED installation. It consists of 170 LED stripes in the form of a large infinity symbol. Unfortunately, I'm not a very good programmer and have been running into some problems.

Here is a part of the patch I am working on that is running pretty slow (depending on the parameters used, it's going down to 5-8 fps). All it really is, is a simple light chase going through all the 170 LEDs. I feel like there is a way to do this that uses less resources or uses resources in a more efficient way.

Right now, I'm sending lots of paintoval messages to jit.lcd to create the points. From there I use getcell messages to sample the points and paint them again (this seems redundant but I will need this or something like it later because I would like to use video input as well, not just jit.lcd).

Does somebody mind taking a look through the patch and giving me a few pointers on how to make it faster? The patch should become much more extensive and I don't want to spend a large amount of time writing it if I'm doing it "wrong".

Greetings from Vienna,
stefan

Max Patch
Copy patch and select New From Clipboard in Max.

Floating Point's icon

gee wiz there is an enormous amount of redundancy in this patch-- stop right now and start all over.
first, if you are only using 170 leds you only need 170 matrix elements, in one dimension ie jit.matrix 4 char char 170 1

I would do it this way: create a static, or slowly changing matrix of 170*1 cells. This is the 'master' matrix-- you could use jit.gradient to generate / alter these values.

then, to create the chase, make another matrix which references the values in the master so that it acts as a kind of conveyor belt of values; maybe alter the source dim settings to do this, but there are other ways

the locations in this second matrix would correspond to the contiguous spatial order of the led lights themselves

hope that makes some sense

Nat's icon
Max Patch
Copy patch and select New From Clipboard in Max.

Something like this ?

Soulthought's icon

Thanks for the quick responses :)

Floating point, I'm not entirely sure if I understand what you mean exactly. What I don't want to lose is the "spatial mapping". Here's an example of what I mean, using nat's patch (thanks nat!). Using the method you describe (if I understand correctly), then "mapping" wouldn't really be possible, or would it? Maybe I'm just not thinking this through correctly….

Max Patch
Copy patch and select New From Clipboard in Max.

Nat's icon

is the output a square led screen or just a continuous led strip that you have shaped a particular way ?

Soulthought's icon

You can see what the output looks like in the attached video (you can't see it very well but around 1:00, there's a good shot of it). I toured this for two weeks with an incredibly stupid Max patch that was capable of very little (time ran out). I'm trying to do things the "right" way now for the summer tour.

Soulthought's icon

It's the same project you answered to previously Nat, sans WS2811 LED stripes. That will be added later, for now I'm just trying to get the "simple" programming in order.

Floating Point's icon

what Nat patched up is basically what i was describing. as far as i understand it, after looking at the vid, the spatial mapping is implicit in the construction of the object itself, (the mobius shape?) so you just decide how to 'wire up' your leds (which Dmx channel corresponds to which LED);

unless you are wanting to 'simulate' what it is actually going to look like on stage, then you may as well go the whole hog and do a 3d open gl rendering

Nat's icon

For performance and simplicity, as Floating Point said, I would try using a single long matrix.

If you want to visualize the output then perhaps build a simulation patch that would be optional.

By the way, we've been working on artnet with the teensy and it's quite nice, you can pump in a lot of universes and performance is great, let's hope David updates imp.artnet to support multiple universes !

Soulthought's icon

Thanks for the input guys, it makes quite a bit of sense now.

I'm getting a few Teensy's next week (hopefully) and I'm excited to try them out. I've been writing with David and it looks he's coming out with some serious lighting software for Max soon. I'm looking forward to see what it's capable of.

Nat's icon
Max Patch
Copy patch and select New From Clipboard in Max.

Just in case you end up using some sections of the patch I sent you on the other thread, I found a much more efficient way to spit out the matrix to either artnet or the serial object than using the mxj object as I was doing :

Floating Point's icon
Max Patch
Copy patch and select New From Clipboard in Max.

...and... here's an adaptation of Nat's patch using jit.repos to simplify the chase

Soulthought's icon

Hey guys. I'm still working on this project and running into some serious difficulties with controlling so many LEDs.

I'm using jit.iter with zl.group to send large lists to the serial object but I've found that if I send more than 1024 values (I'm trying to send a 200x8 matrix, so the most that works is 170x2), that the output gets truncated and all messed up in general. It seems that the serial object can't send more than 1024 values in a single frame.

Can someone suggest a workaround?

Max Patch
Copy patch and select New From Clipboard in Max.

I've posted my patch as well as the Arduino sketch I'm using (Teensyduino needed)

[quote]
[color=#7E7E7E]/*  OctoWS2811 BasicTest.ino - Basic RGB LED Test[/color]
[color=#7E7E7E]  Required Connections[/color]
[color=#7E7E7E]  --------------------[/color]
[color=#7E7E7E]    pin 2:  LED Strip #1    OctoWS2811 drives 8 LED Strips.[/color]
[color=#7E7E7E]    pin 14: LED strip #2    All 8 are the same length.[/color]
[color=#7E7E7E]    pin 7:  LED strip #3[/color]
[color=#7E7E7E]    pin 8:  LED strip #4    A 100 ohm resistor should used[/color]
[color=#7E7E7E]    pin 6:  LED strip #5    between each Teensy pin and the[/color]
[color=#7E7E7E]    pin 20: LED strip #6    wire to the LED strip, to minimize[/color]
[color=#7E7E7E]    pin 21: LED strip #7    high frequency ringining & noise.[/color]
[color=#7E7E7E]    pin 5:  LED strip #8[/color]
[color=#7E7E7E]    pin 15 & 16 - Connect together, but do not use[/color]
[color=#7E7E7E]    pin 4 - Do not use[/color]
[color=#7E7E7E]    pin 3 - Do not use as PWM.  Normal use is ok.[/color]

[color=#7E7E7E]  This test is useful for checking if your LED strips work, and which[/color]
[color=#7E7E7E]  color config (WS2811_RGB, WS2811_GRB, etc) they require.[/color]
[color=#7E7E7E]*/[/color]

#include 

[color=#CC6600]const[/color] [color=#CC6600]int[/color] ledsPerStrip = 200;

DMAMEM [color=#CC6600]int[/color] displayMemory[ledsPerStrip*6];
[color=#CC6600]int[/color] drawingMemory[ledsPerStrip*6];

[color=#CC6600]const[/color] [color=#CC6600]int[/color] [color=#CC6600]config[/color] = [color=#006699]WS2811_GRB[/color] | [color=#006699]WS2811_800kHz[/color];

[color=#CC6600]OctoWS2811[/color] leds(ledsPerStrip, displayMemory, drawingMemory, [color=#CC6600]config[/color]);

[color=#CC6600]void[/color] [color=#CC6600][b]setup[/b][/color]() {
  [color=#CC6600][b]Serial[/b][/color].[color=#CC6600]begin[/color](12000000);
  leds.[color=#CC6600]begin[/color]();
  leds.[color=#CC6600]show[/color]();
}

[color=#CC6600]void[/color] [color=#CC6600][b]loop[/b][/color]() {
  [color=#CC6600]for[/color] ([color=#CC6600]int[/color] i = 0; i < ledsPerStrip*8 ; i++) {
    [color=#CC6600]int[/color] timeout=[color=#CC6600]millis[/color]();
    [color=#CC6600]while[/color]([color=#CC6600][b]Serial[/b][/color].[color=#CC6600]available[/color]()
      [color=#CC6600]if[/color](timeout+1000
        [color=#CC6600]return[/color];
    }
    leds.[color=#CC6600]setPixel[/color](i, [color=#CC6600][b]Serial[/b][/color].[color=#CC6600]read[/color](),[color=#CC6600][b]Serial[/b][/color].[color=#CC6600]read[/color](),[color=#CC6600][b]Serial[/b][/color].[color=#CC6600]read[/color]());
  }
  leds.[color=#CC6600]show[/color]();
}

[/quote]

Any help would be great!
Thanks!

Nat's icon

You would probably need to split your output in 1024 chunks and then recreate the complete frame in the arduino sketch.

Nat's icon

Hmm thinking about it, the serial object can also just take a steam of numbers, did you try just plugging the jit.iter directly in the serial object ?

Soulthought's icon

I will try that on Monday, when I have access to the LEDs again. Thanks for the help :)