These are chat archives for Makuna/NeoPixelBus

1st
Sep 2015
zephyrr
@zephyrr
Sep 01 2015 06:36
Hi, I've just encountered your library and while most of it makes sense to me (nice job), you are using some C++ features which I do not understand. Alas, I'm not even sure where to look for insights.

In particular, NeoPixelAnimator.cpp line 81 (currently) (https://github.com/Makuna/NeoPixelBus/blob/NeoPixelAnimator/NeoPixelAnimator.cpp#L81) consists of:

AnimUpdateCallback animUpdate = =

zephyrr
@zephyrr
Sep 01 2015 06:44

@Makuna Oops, don't know how to quote code here yet. You can see the line. Like the equal sign between square brackets - I don't know what that syntax means, and it's not exactly google searchable until I have a textual name for that syntactic delight! I'm hoping you can give me some tips for understanding the code. (I am guessing that it has to do with std::function, which I admit I do not yet understand).

I'm also wondering why you did not use a function pointer, or a virtual member function (which I understand better). Understanding your reasons would help me see not just what it does, but why.

Is that the only reason you need the std c++ library?

sticilface
@sticilface
Sep 01 2015 06:44
This is a new c++ function. Lambda function.
i agree. Search for = does not yield much!
Michael Miller
@Makuna
Sep 01 2015 06:47
The key feature here is that you don't have to create some custom structure to contain args that is passed as a non typed pointer and inside have it cast it back, and then managing lifetime of said container. The compiler is smart enough to do this work for you.
zephyrr
@zephyrr
Sep 01 2015 06:48
And ... the reason this intrigues me is that I've been fermenting a pixel controller design with a few similarities and a few differences. Mostly "on paper" (er, as text notes rather than code). So it's fun to see your solutions to a related design issue - a structure for arrays of LEDs and effects.
Michael Miller
@Makuna
Sep 01 2015 06:48
The [=] is a option for lambda stating that the variables used are values not references.
zephyrr
@zephyrr
Sep 01 2015 06:49
I'm going to have to do some reading, thanks for the pointer. Is this part of #include <functional>?
It looks like the original was NeoPixelBus, wherein you added some functions to Adafruit's NeoPixel library and conceptualized a given string (hanging from a given pin) as a "Bus" object, along with a prototype animation support. Then NeoPixelAnimator branch expands upon and generalizes the animation (adding some color functions). And then there is the multibus version which supports multiple NeoPixelBus's as well as the animation. Right?
Michael Miller
@Makuna
Sep 01 2015 06:51
It's part of c++ 11, but functional gives you easy ability to store them as variables. Due to AvR missing functional, this won't work for Avr in this case, but lambdas are available there also.
zephyrr
@zephyrr
Sep 01 2015 06:52
Oh, and - critically - added ESP8266 support!
Michael Miller
@Makuna
Sep 01 2015 06:55
All branches support esp8266, it's just the others start to do things that the avr cant. The multibus branch will drive 3 pins in the same time to run just one of the others, allowing more pixels to be updated as long as they are seperated onto different busses.
A bus is more accurate description of pin
zephyrr
@zephyrr
Sep 01 2015 06:56
Is MultiBus the next step after PixelBusAnimator? Superficially it appears to be a superset.
Michael Miller
@Makuna
Sep 01 2015 06:57
Multibus requires running at the faster cpu speed, but all the chips can do it, albeit slightly more power draw.
Multibus is experimental and still under developement.
It functions though.
zephyrr
@zephyrr
Sep 01 2015 06:58
Cool. Thanks. I'll try to check back later to see where you've gotten to. I'll go star your repo to remind me.
Michael Miller
@Makuna
Sep 01 2015 07:00
If you have feature suggestions, post them here or create an issue
zephyrr
@zephyrr
Sep 01 2015 07:01
Well, I want to drive APA102's (I think Adafruit calls them dot star or some such). Are you thinking to support anything but the WS281x family?
Michael Miller
@Makuna
Sep 01 2015 07:11
When ever I get some, sure. They should be simpler if I remember correctly as they have a clock pin, less timing sensitive. The ws281x family are just so cheap right now. I can get the chips mounted on small single boards for less than 25 cents.
zephyrr
@zephyrr
Sep 01 2015 07:12
OK - later. Thanks for sharing (and the tips).
sticilface
@sticilface
Sep 01 2015 09:56

@makuna I've got a fairly nuts idea... and I'm not sure if / how it might be implemented... but i've got a habit of over complicating things, so i thought i'd share it with you as you might have a simple solution... the problem..
1) animations at low brightness, especially when slow, are VERY steppy...

lets say for example you want to fade red from 0 to 255 over 10 seconds... that is smooth... the LED gets brighter 25 points / sec, which is 1 point every 40ms, which is quite smooth..

but lets say you want to fade 0 to 5 over 10 seconds, then that is one point every 2 seconds, and it looks really bad...

the solution... would be do have dithering of some description... seeing as the pixels are being updated every 30ms (or more or less) MOST of the time they are not doing anything.. this none time could be used to pulse them up and down 1 point so that the average is a smoother transition between animations. I had a go at making this but it didn't work at all. what do you think, achievable or far to complicated?

Shelby Merrick
@forkineye
Sep 01 2015 13:41
Dithering will suck up resources and cut down your refresh. You can map them out to a brightness curve with a pseudo-gamma table like this - https://github.com/forkineye/ESPixelStick/blob/master/ESPixelDriver.h#L30
Dithering would look better and give a higher dynamic range of course, as the expense of resources
this explains it better than i - http://rgb-123.com/ws2812-color-output/
sticilface
@sticilface
Sep 01 2015 13:53
I've already integrated that lookup table.. stole it from you actually ;) I understand that it will take resources... from the animation point of view, when the changes are small, and over a long period of time, it looks rubbish, especially at low brightnesses. my thoughts were in cases like what i've described here, there is no 'refresh' rate... the byte for the LED, only changes every few seconds.. I'm wondering if there is a way of coding the animation to realise this then employ dithering, to make it smoother.
I've had a look at the animator code... and i think this might be better handles in the animator callback... so i'll take another look at it!
Shelby Merrick
@forkineye
Sep 01 2015 14:04
ah, i gotcha. shouldn't be that bad to implement for the animation stuff.
sticilface
@sticilface
Sep 01 2015 15:17
i've had a couple of goes... but i think my coding / thinking / method is not right... i can't get it to work, hence me putting it out there!
Michael Miller
@Makuna
Sep 01 2015 17:14
Sometimes the best solution is not software. These leds are horrible at low and high brightness levels. Unless you put them behind a filter to diffuse/dim them to put the brightness into the sweet spot. I also wonder about the dotstars. But...
As forkineye stated, h
Using a PWM model to alternate between two colors is going to consume resources. Another solution is subpixel dithering, TruType fonts do this.
Have the blend method only blend one channel step on a series of updates, then another channel update on another. So green goes up this second, then red the next second, then blue to reach the one step animation.
sticilface
@sticilface
Sep 01 2015 17:25
the dot stars are a lot faster! but in the end still 8bits....
per colour
my thought was say you were blending from a 0 to a 1 over lets say 10 seconds... if you put out 1010101010 you would have on average... a 0.5 . if you put out a 110110110110 then it would be 0.66, 100100100100 = 0.33... so with there three you could have 0, 0.33, 0.5, 0.66 and 1 in between. however, i've tried to implement this and failed magnificently... could this work?
sticilface
@sticilface
Sep 01 2015 17:30
to get this to work i'd need to know how far along between changing from a 0 to a 1 i am in the current animation sequence, which is a bit complicated..
Michael Miller
@Makuna
Sep 01 2015 17:31
It's not just about the bits per color, it's about how they translate that into light. With neopixels, above about 230 it's extremely hard to see any difference unless you put it behind a strongly tinted filter. The neos just translate dirently into a pwm without a curve.
It can work, but you will need to refresh each step you are showinng at a refresh rate of no lower than 24hz, so in total 48hz minimum otherwise you get obvious flicker as you move your head.
sticilface
@sticilface
Sep 01 2015 17:35
you can push out pretty quickly, 10ms = 500 LEDs. i think.. so for 144 you can manage that refresh i think.
Michael Miller
@Makuna
Sep 01 2015 17:36
A hint, the blend gives you progress into a value, what you need to find is the amount of progress that would cause change, then use this to know when to step.
sticilface
@sticilface
Sep 01 2015 17:48
cheers.... i will have another stab at it!
sticilface
@sticilface
Sep 01 2015 19:23
im not sure it will work... worth a try though!