I haven’t seen this documented: the LPD8806 pixels show as full OFF for 0, 1, 2; their dimmest level is at 3 and 4, then 5 and 6. As they have only 7 bit dimming that makes some sense, but why is 3 & 4 the dimmest rather than 2 & 3? Why not just shift right by one to map 0…255 inputs to 0…127 outputs?
I believe this is a side effect of the fast scaling code that we’re using - which is basically multiply by 255 (assuming you’ve set brightness to max), shift right 8, which won’t actually leave you with the same value you started out with. 2 left shift 1 (for the LPD8806 conversion) gives you 1, multiply that by 255, then shift right 8 (which is the fast scaling op) - and you get 0.
Can the scaling be disabled?
Sending full on (255) through the new library presumably results in the chip (any chip, not referring now to the 8806) receiving 254, right? That explains why in my PWM test I thought I saw a small dark line even when trying to set full on.
Not with the currently library, it can’t, and I just realized this was going on a few days ago. Because of how tight the timing/spacing is, it would need to be a compile time option (most likely with a template parameter) - and i’d have to adjust the timing code for strips like the ws2811 which currently take the 2 cycles for the scaling into account.
I suggested another option - making the scaling more accurate for all values - in a newer thread. It would mean adding two instructions to the scaling multiply - or maybe three if one needs to save a copy of the channel value. There may no be time for that in your code.
I’m guessing that your code is too tight for that.
One effect may be that we cannot use your library to set current (amperage) values for the 1829, if we cannot send FF values.
So - this is all moot for the 1829 - and in fact, in an odd way, this scaling artifact makes the 1829
easier to support.
The way the 1829 protocol works is, for a 3 byte rgb value, if the first 8 bits are all 1’s, then the next 16 bits (er, 15 bits, with one throwaway bit) are used to set the 0-31 constant current brightness levels for the 1829. If the first byte is not 8 bits all 1, then the 24 bits do rgb pwm brightness setting like you expect w/ws2811/tm1809.
So, in a weird way - the side effect of the scaling, that when the level is 255 you end up with 254, gives me that differentiation for tm1829 in PWM mode for free.
(Isn’t the variety of options and effects and platforms and considerations and timings and performance hits and performance improvements and more fun? I’m being serious here - I love juggling all this stuff, this library wouldn’t exist if I didn’t get some level of joy out of figuring out how to get this all to work and play together as smoothly as possible. Time, on the other hand, I need to sit down and have some words with time
You have picked up a very complicated puzzle. Moving one piece may affect various other pieces, in ways that you may be able to compensate for, but sometimes with still further implications. Compared to a Rubik’s cube, the “moves” (and the side effects) are much less constrained - you get to throw in totally new and creative techniques.
Being a sometimes bit twiddling optimizer myself, I can appreciate your efforts including some of the nuances. But I’m glad you are finding the time to play with this puzzle, because it does take time.
(For myself, I’d rather spend the hours - if I had them to spare - doing what you do than on TV or mastering a video game, but it does take many hours; and to each their own priorities).
IF you wind up keeping the off-by-one dynamics for the sake of the 1829, please do comment on that in the source code! Relying upon “convenient side effects of partly incorrect code” can leave nasty pitfalls around.
BTW, ave you tested the current setting ability of the 1829 yet?
As for documenting - definitely - it was kind of a surprise, however I don’t have the TM1829 working reliably in PWM mode yet (timings changed, yet again - and they appear to be a bit tighter - also, my seller couldn’t tell me if what I got was 1.6Mhz or 800Khz chips headdesk) - and still need to think about how I want to handle the constant current mode - because, well, see the problem of clock cycles and converting the 0-255 levels people will expect to use w/CRGB class to 0-31 that tm1829 expects in constant current mode (Leaning towards just taking the top 5 bits of the RGB values - but I suspect different people will have different comments about how that doesn’t exactly work for them
Somebody reported that Ray Wu only stocks the half speed 1829 so far (ie: same as the full speed 2811/180x at 800 Kbps), because the controllers he has only support that speed. I would not be surprised if that’s the case with others, if you did not go through Ray.
I did go through ray - however while the speed is 800Khz, the distribution of hi/lo timings is a bit different. To make life more fun, the meaning of hi/lo on the line has been swapped Where ws2811 is hi then lo for bits, the tm1829 is lo then hi.
The more I dig into it as a chipset, the more I feel like “good idea, terrible execution” - i’m curious to see if it will ever pick up in quite the way that ws2811/lpd8806’s have.
at least, I believe the speed is 800Khz - the strip does different things with the 800Khz timings than the 1600Khz timings - but it all still works horribly at the moment.
As for making use of the current control modes, good question.
First Option: Set the current in the constructor; this should be set according to the hardware and what it can tolerate (power supply, heat dissipation, voltage drop, ampacity of the wiring…).
AND have an option (on by default for this chip) to filter out 255 values (remap to 254 or use the scaling limit or whatever) in the brightness data so people don’t accidentally change the current and burn something up.
I say option, because it would be nice to allow us to disable that and easily control the current if we want to experiment.
Let enough people like me experiment with dynamically setting the current before designing a fancier interface into a later version of the library. The fancy interface might allow 8 bits of gamma encoded table to be translated into 8 bits of PWM plus a few bits of current modulation - within the safe range (from 10 ma to the configured maximum). This could all be tested using library clients before being integrated into the library.
We don’t really need any more resolution in the upper value ranges (can anybody see the difference between 255 and 250?) But once you get down toward single digits of PWM, being able to change the current as well as the PWM value might buy us some useful visual levels. However this means sending twice to the string - once to set the current and once to set the PWM - which might cause some flicker. Some experimentation is needed.
The other thing I’d want to play with is deliberately overdriving the LEDs with more current than they can sustain (eg: which would overheat them), for a short period of time, to produce a strobe or lightning effect. So set the PWM low, then max the current at 41 ma, then send 254’s, wait a few ms, and drop both back down again to safe levels. I don’t expect the library to do that, just let me do it by allowing me to send FFs after calling an appropriate function to disable the default filtering.
The current isn’t constant - it’s set on a per pixel basis - it’s 32 levels of current for each r, g, b across the board, 32 levels of brightness.
Right now my plan is to provide two controllers - one using TM1829 in PWM mode, and one using TM1829 in the adjusted current mode.
That second mode is the one that will have to map 0-255 in CRGB down to 0-31.
My read of the data sheet was that it was an either/or thing - either you can PWM or you can set the current for brightness levels.
Also - I have support for a couple of 4096 vs. 256 brightness level chipsets coming down the line. I’ll need to work out how to add support in for those as well.
That said - if the chip works such that there’s setting the current separately from setting the PWM - but that you can mix and match them - there’s both a recipe for disaster in there, and a small bit of disappointment - I was hoping for non-pwm based brightness adjustment
Also the fact that you then would blow an entire frame to change the current level makes the usability a lot less as well, because if you’re doing a lot of dynamic color work, you just halved your frame rate all over again, worst case scenario
As far as I can tell - and this is why we need to test - the current is set by sending an apparent brightness of FF to the first channel; you could send PWM to pixel 3 (no higher than 254 tho) and current to pixel 4 and back to PWM for pixel 5.
Given the range of current (10 to 41 ma) I don’t think it was designed for doing dynamic brightness modulation, so much as to allow soft configurable current rather than requiring resistors to “program” the current.
The 10ma minimum is not “off” and 10 to 41 ma will allow far fewer than 31 perceived brightness levels.
I’ve mentioned a couple of possible repurposed uses - strobes and adding resolution to the low end of the PWM. But these will need experimentation.
And I agree that it’s a potential problem to let people accidentally set their current to 41 ma; that’s why I think the default should indeed not allow a brightness of FF for the first channel. I just want to be able to control the current if I intend to, knowing the risks.
I can read enough of the data sheet to know that this is, in fact, what the protocol is.
If the intention for the constant current is per-led adjustment, then what i’d do is have two separate operations available - one to set the PWM values (and given that i already have code in place to deal with limiting adjustments based on chipset requirements, this will fall into that) which will cap them at 254, not 255. (Looking at the data sheet and the range of current values available - that’s looking like what it’s thinking of).
Then a separate operation for setting the current - either globally or per-pixel. Then to figure out how to expose this to users in a way that won’t have them blowing out strips/power supplies
I’m not entirely sure i’d want to allow - in this library - mixing setting the current with setting the pwm levels. Or I may make it a fire/forget kind of thing.
First, though, I need to get its ass backwards data protocol working at all, for setting either PWM or current.
Also, to continue the search for PWM-less led setups
I’m interested in this chip in order to play with the current settings and see what’s worthwhile and what isn’t. As you say, perhaps PWM-less chips may yet appear, and this is the first chance to play with even a limited version of it.
And I like the higher PWM speed. I find the 2801 and 8806 nicer to view at close distance than the 2811 and 180x chips - but three wires is handy sometimes. The 1829 combines a three wire pixel with higher PWM, even without the current control feature.
IF the library can talk with it. Thanks for tackling that.