Multisegment for Home Automation Systems - Fades and Brightness

Hello! My project involves replacing my incandescent rope lights in my home theater room with LED’s. Presently I use an AMX NetLinx controller to drive a DMX dimmer pack with 120v rope lights for accent lighting. I bought a Pixelblaze and some RGBW SK6812 LED strips running @zranger1 's Multisegment Pattern for Home Automation Systems pattern. It seems like the perfect fit for what I’m trying to do and it is looking to be quite promising! I have managed to get my NetLinx system to send Websocket messages to the Pixelblaze and control the individual patterns in the separate zones just fine. The one thing I’m having troubles with is tweaking the code in the Multisegment pattern.
You see, Multisegment has several built in patterns, one of which is solid colors. However if I tell to be white at 50%. It just snaps right there immediately which is too jarring compared to my smooth dimming I have in the old system. I was wondering if I could get assistance with what I suppose is a feature request to allow for changing to a different brightness and use the speed variable to tell it how fast to get there. i.e. if it zone 0 is presently 0% brightness and I tell it to go to 50% brightness at speed x, it then slowly ramps from 0 to 50% over speed x. Then subsequently if I tell it to go to 20% brightness over speed x, it slowly ramps from the previous 50% to 20%. Also this should be for just the one zone in question, not global brightness. I’m more of a hardware guy and after tinkering around with the code I decided to break down and ask in case it’s a simple thing. I’m hoping it is. :slight_smile:
Thanks in advance for any advice!

Hi and welcome, @Dan-Tron!

Glad to hear that you’ve got the multisegment pattern working. I didn’t include smooth level transitions in previous versions mostly because it was written for Pixelblaze v2 and I was pushing CPU and memory limits as it was.

Now that we have Pixelblaze 3…

Check out this morning’s experimental version in my Github repository and let me know if it does what you need. When you set segment brightness, this version does a slow transition from the previous state to the new one. Currently the transition speed is controlled by the variable fadeLength, around line 45 in the pattern code. If this works, I can make it use speed for the next version.

(Note that this is the home automation version. If you need the demo version with the sliders, let me know and I’ll put an updated one together. For now transitions just work with brightness - interpolating color and crossfading between effects are some distance down the road.)

1 Like

Thanks for the quick response! I just tested it out. It does work pretty good but might need some tweaks. I changed around the value for fadeLength and found the dimming times to be somewhat strange and unexpected. Also on slow fades towards the end it gets a bit steppy/chunky. Though I’m not so sure how much to ask of it. Most of the time my fades will be in the half second to 3 second ranges. I do like that I can send a new brightness in the middle of another dimming transition and it just naturally corrects form where it is.

I sent this for 100% white
{“setVars”:{“z_0”: [1,0,0,1,0,74,2]}}

I sent this for 0% white
{“setVars”:{“z_0”: [1,0,0,0,0,74,2]}}

100% to 0% at var fadeLength = 10000 actually took about 5 seconds
100% to 0% at var fadeLength = 5000 actually took about 25 seconds
100% to 0% at var fadeLength = 1000 actually took about 5 seconds
100% to 0% at var fadeLength = 500 actually took about 3 seconds

Non-linearity was baked into that version and fadeLength wound up being arbitrary units, not milliseconds. It was computationally super cheap! But it should have been a very very slow fade at 10000. Looks like fixed point integer underflow!

I’ve just updated the repo, with new improved, rescaled calculations that will give you better control. The most important difference is that fadeLength is now in seconds.fractional seconds (NOT milliseconds, or random fade units).

It is also exported, so you can set the fade time from your controller. Note that fadeLength is global, not explicitly per channel, but once a fade has started, you can change fadeLength freely without affecting running fades. It’s still possible to
run off the edge of fixed point math with a long enough fade, but this version can handle at least 30 seconds.

Re: what happens at low brightness - this is a linear fade, and LED brightness (and color) at low levels isn’t really very linear. You may see a pretty fast falloff from about 1% on down with SK6812 and other WS2812 type LEDs.

Anyway, take a look when you get the chance and let me know what you find!

The fades in this version are amazing. Much better. At least at first. As I play with it and especially if I start adding other zones and solid colors, it seems to get unstable in terms of the fade time. Like the fade timer is still happening in the background but the lights aren’t changing anymore and then suddenly go off or on along with other general strangeness that is hard to explain.

Oh and I had left it sitting idle with all LED’s off for several minutes and my Zone 0 suddenly turned on randomly. Haunted! I’m guessing some math is leaking out somewhere.

I’ll check it out tonight and see if I can figure out what’s going on. It is definitely not supposed to be haunted!

Ok, one more time! I’ve updated the code in the repository once again.

The problem was this: I expanded one of the arrays that can be written via websocket, thinking that everything upstream would automatically be Ok with this. And it is… …most of the time…! Thus the intermittent hauntings.

New stuff is now safe in its own data structures, everything appears to be working and stable. Try it out when you get a chance and let me know.

I think it is mostly the same. Basically the more I use it and turn on and off multiple zones, it seems to degrade with latent action and/or fade faster than normal as though it is trying to fade but doesn’t display it until nearly done fading. As it runs the lag seems to get progressively worse. That’s what that ghostly lights turning on before was, it was just lagging so much my last command finally caught up. For a second I thought maybe it was because I have two websocket connections going, one from AMX and another from my PC using Websocat. But it seems to eventually do strange things even with one websocket connection. Is it maybe trying to loop the effect like the other effects? Effect 0 is the only one I would imagine should run once and then stop, vs say rainbow where it’d loop indefinitely. As I type this post, the zones are going on and off every minute or so and those don’t seem to be latent commands as I didn’t send that many. I can make a video if that helps describe it. Also thank you for the help so far!

Edit: Ok. I can repro the problem if I push the commands just a little bit faster. You might want to go back to the pre-fade version of multisegment for a day or two while I sort this out. There’s definitely something strange going on in there!

I ran it overnight, doing a bunch of automated switching and fades, and it’s still behaving itself, so there may be something else going on. Here are a few things to try.

First, the paranoid option: be absolutely certain you’re running the latest version from the experimental repo: multiseg3.js. There’s a slight possibility that something went wrong during the save process, per this thread:

A fix is in the works, but for caution’s sake when saving, I note the pattern’s frame rate beforehand, press save, then touch nothing 'till the frame rate has returned to its prior value. Get the pattern saved, then switch to another pattern for a second, switch back and check code in the editor to make sure everything’s OK.

Also, check/restart your controller to make sure it didn’t save any data from the previous version, which had the JSON array size problem. If the controller was using getVars, it might have grabbed an incorrectly sized array, and sending it back to the Pixelblaze would definitely cause weirdness. This version uses the original 7-element controls - state, hue, sat, brightness, effect, size, speed.

Effects should be be fadeable too, so effect setting should have… no effect at all. But it is possible to overrun the websocket connection with data, which could cause the lag. My controller is relatively slow and only sends data for one segment at a time so I might not have seen this. If nothing else works, see if you can add a short delay, maybe 50-100ms to start with, between websocket commands.

Meanwhile, I’ll set up a Python testbed this afternoon to stress it more and see what I can shake out.

I still had issues but I’ll need to take more time to try again later today in case I am missing something.
My PixelBlaze is running v3.20 and I am using the Output expander. Do you think I should upgrade to v3.21 or v3.22? I haven’t yet read up on how to install firmware.

Also I wanted to share how I am initializing it just in case I misunderstood how to do that. I want to be sure I’m not making some n00b mistake.
Via Websocat I connect to the the Websocket.
I see the continuous updates with FPS etc.
I get the list of programs: {“listPrograms”: true}
I find the ID in front of Multisegv3 and run it: {“activeProgramId”: “2gFYA3AzqiAD7untZ”}
Initialize: {“setVars”:{"__n_segments": 4, “__boot”: 0, “__state”: 0}}

I toggle Z0 a few times and it works ok at first:
{“setVars”:{“z_0”: [1,0,0,1,0,74,0.5]}}
{“setVars”:{“z_0”: [1,0,0,0,0,74,0.5]}}

Then I start toggling Z1:
{“setVars”:{“z_1”: [1,0,0,1,0,74,0.5]}}
{“setVars”:{“z_1”: [1,0,0,0,0,74,0.5]}}

Then strange things begin happening. Fade stops working on Zone1 and the light lags and then suddenly pops on. Also if I leave it sit the lights on both zones will go on and off every minute or few minutes without any input.

I’ll do more testing again later today. I’m sorry my little fade request is turning into a strange conundrum at least on my side. :-/ But also thanks for your help!

@dan-tron, it’s not you at all. There were definitely bugs in the pattern. I’ve got a working fix, and a test program that is thrashing the heck out of it overnight to make sure. Will post it tomorrow after I’m certain it’s solid.

I’ve just checked in the latest version of the multisegment, hopefully with all previous bugs resolved.

Be sure you’re getting the v3 version. Older versions, for older controller drivers, are still in the repo folder.

Biggest change: It now supports per-segment setting of fade in/out times. To use this feature, you’ll have to add a new, eighth element to the JSON array that controls it. The new column is fade transition time for that segment, in seconds (again, not ms), and its effective range is 0.0 to 30.0 seconds.

After testing, I decided that linear fades were not really ideal looking, so it now uses exponential fades that always move slowest at low levels for the smoothest look.

If you’re reading this and are not familiar with the multisegment pattern, and would like to see it or learn how to program it via websocket, I’ve also checked in a small Python testbed program,

You’ll need to edit it with your Pixelblaze’s IP address to run it. It creates 12 segments, and fades them up and down at random speeds, setting colors and effects along the way. Visually very weird to watch, but it does show the possibilities.

Looking real good! I tested it and it seems to be working as expected so far. Seems stable. :slight_smile:
The exponential fades look good, although on slower fade to off’s it tends to get chunky at the end. However my fade times are typically going to be 1 to 3 seconds and it doesn’t seem too evident at those speeds.

I tried running the Python test program but it seems to reference a pixelblaze import that I don’t have or something like that.

In any case it does work form my AMX system and now I have to work on my NetLinx code to add all these fancy features into my automation system. I’ll be sure to share the final product once I have it ironed out. Awesome work! Thank you!

I’ve been thinking of applying a simple Bayer dither (e.g. Ordered dithering - Wikipedia) with some temporal shifts to smooth out my WS2812B matrix displays. If it’s any good I’ll let you know :relaxed:

1 Like

@dan-tron, you can get the Python pixelblaze library by typing

pip install pixelblaze-client

on a command line from which you can use Python. It’s really handy for testing and debugging. More information in this thread.

One thing to be aware of while automating: right now changing the segment state doesn’t trigger a fade. Only level changes do.

So if you want smooth on/off switching, the best way to implement that is to have the controller store the current level and fade to 0 for off, and fade back up to the stored level for on. The controller is generally an easier place to store persistent information anyway.

I’ll change this in a future version. It’s a consequence of architecture - the array you send via websockets is not commands, it’s actually the internal state of the pattern, which gets applied pretty much instantly. The state/switch element is right now, an absolute render/don’t render switch.