jandelgado / jled

Non-blocking LED controlling library for Arduino and friends.
MIT License
331 stars 55 forks source link

FadeTo method #66

Closed JuMiLo closed 1 year ago

JuMiLo commented 3 years ago

Hi and thanks for your awesome library! The only feature im missing is something like a FadeTo(duration) method, which works like FadeOn/FadeOff, but without switching the LED on or off.

JLed(pin).FadeTo(duration).MaxBrightness(155) should fade the LED from any level to level 155.

Being an Arduino/C++ beginner, i don't know if this would be possible with a user class but maybe the method would be usefull for others too :)

jandelgado commented 3 years ago

The current output level of an LED is determined by evaluation the associated brightness evaluator, which is basically a function of time and period that returns a brightness level between 0 and 255. JLed does not "store" the currently output brightness value, it is evaluated when needed. So I think there is currently no easy way for a "new" effect to take over the "current" brightness level into account.

Generally, a user defined brightness evaluator (for an example look here https://github.com/jandelgado/jled/blob/master/examples/user_func/user_func.ino) could be used to have a general Fade(fromLevel, toLevel, period) where both start and end brightness level are specified.

simonchen007 commented 3 years ago

how to make a Fade(fromLevel, toLevel, period) function ?

jandelgado commented 3 years ago

That's left as an excercise to the reader ;) - I'll try to provide an example in the next days... Look at #72 for another example for a user defined brightness function.

maxmlr commented 3 years ago

Amazing library, thanks @jandelgado for the work you put into this! I agree that the addition of a basic FadeTo would really be of great value here. An example how to do this with a user defined brightness function would certainly help a lot, however I still think that a generic fade from current value X to target value Y capability would be a good addition to the library.

leistungszentrum commented 3 years ago

The following should work for a user defined "fade from value x to value y":

#include <jled.h>
#include <math.h>

class FadeFromTo : public jled::BrightnessEvaluator {
    const uint8_t from_;
    const uint8_t to_;
    const uint16_t period_;
 public:
    explicit FadeFromTo(uint8_t from = 0, uint8_t to = 255, uint16_t period = 1000)
        : from_(from), to_(to), period_(period) {}
    uint8_t Eval(uint32_t t) const override {
        const uint8_t pos_ = jled::fadeon_func(t, period_);
        const uint8_t pos = map(pos_, 0, 255, from_, to_);
        return pos;
    }
    uint16_t Period() const override { return period_; }
};

However, when trying to call it:

int pin = 12;
FadeFromTo userfade(50, 200, 1000);
JLed(pin).UserFunc(&userfade);

I run into an exception. Did I miss anything?

jandelgado commented 3 years ago

Hi, could you pleas post the complete sketch? On which micro controller are you testing?

github-actions[bot] commented 3 years ago

This issue is stale because it has been open 90 days with no activity. Remove stale label or comment or this will be closed in 5 days

ghost commented 2 years ago

Any news about this feature? It would be super useful to make a smooth fade affect within a specified amount of time, starting at the current brightness level.

jandelgado commented 2 years ago

I've put the request ob top of the backlog and will start working on it

jandelgado commented 2 years ago

I think the best solution, which also would work with other effects, would be to introduce a MinBrightness method and scale all effects to [minBrightness, maxBrightness]. That would also allow to fade from on value to another, e.g.

auto led = JLed(2).MinBrightness(100).MaxBrightness(200).FadeOn(1000);

would fade from 100 to 200. Would that help? @maxmlr @Mark-81 @JuMiLo @simonchen007 @leistungszentrum

ghost commented 2 years ago

From my point of view, it's still limited in the way you proposed. No need to specify a MinBrightness neither to use brightness only. In my opinion, any effect should specify the desired target configuration (i.e. color, brightness, etc...) to be reached in a specified amount of time.

The code should just calculate the steps not from 0 but from the current state, even if the previous fade is still running.

jandelgado commented 2 years ago

Just to make sure we are thinking in the same directions: in the case of the FadeOn effect for example, when starting the fade with some value (which is currently always 0 like in (A)), we want to see a "scaled" version of the effect, like in (B) in this example:

image

ghost commented 2 years ago

Exactly!

jandelgado commented 1 year ago

@Mark-81 @JuMiLo: i have add a Fade(from, to, duration) method. Please check out commit a8c40a310b1eac325243d92103cbd0b656455ba0 to test it - thanks

jandelgado commented 1 year ago

Released with 4.12.0 https://github.com/jandelgado/jled/releases/tag/v4.12.0