Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FadeOn and stay on forever #88

Closed
oscgonfer opened this issue Feb 22, 2022 · 7 comments
Closed

FadeOn and stay on forever #88

oscgonfer opened this issue Feb 22, 2022 · 7 comments

Comments

@oscgonfer
Copy link

Hi,

Thank you for this fantastic library. I am working with it on a SAMD21 M0 (Feather RFM69) with the following code:

#include <jled.h>

// JLED
#define LASER_PIN       10
#define FRONTLIGHT_PIN  11

JLed pwm_pins[] = {JLed(LASER_PIN).Breathe(255).Forever(), JLed(FRONTLIGHT_PIN).Off()};
JLedSequence sequence(JLedSequence::eMode::PARALLEL, pwm_pins);

One of the packets received on the radio, triggers the following:

void laser_fade_in_slow(int brightness) {
    if (brightness){
        pwm_pins[0].FadeOn(FADESLOW).MaxBrightness(brightness);
    } else {
        pwm_pins[0].FadeOff(FADESLOW);
    }
}

I am sure I am missing something, but I am unable to figure out how to make it stay on at the desired brightness level forever, only getting a loop with the same FadeOn.

Could you give some guidance?

Thanks in advance

@oscgonfer oscgonfer changed the title FadeOn and Stay Forever FadeOn and stay on forever Feb 22, 2022
@jandelgado
Copy link
Owner

How often is the laser_fade_in_slow function called?

@oscgonfer
Copy link
Author

On demand, i.e. triggered remotely, but never anywhere close to intervals shorter than FADESLOW, which is 3000ms. Basically the idea is to turn the "laser" on with a fade in but leave it on after that until another function makes it turn off.

@jandelgado
Copy link
Owner

jandelgado commented Feb 24, 2022

I think you need to change to something like:

#include <jled.h>

#define LASER_PIN       21
#define FRONTLIGHT_PIN  22
#define FADESLOW 3000

JLed pwm_pins[] = {JLed(LASER_PIN).Breathe(255).Forever(), JLed(FRONTLIGHT_PIN).Off()};

void setup() {
    Serial.begin(9600);
}

void laser_fade_in_slow(int brightness) {
    if (brightness){
        Serial.print("Set to FadeOn with brightness=");
        Serial.println(brightness);
        pwm_pins[0].FadeOn(FADESLOW).MaxBrightness(brightness).Repeat(1).Reset();
    } else {
        Serial.println("Set to FadeOff");
        pwm_pins[0].FadeOff(FADESLOW).Repeat(1).Reset();
    }
}


void loop() {
    static unsigned long last_change_time_ = 0;

    pwm_pins[0].Update();
    pwm_pins[1].Update();

    delay(1);

    // simulation: every 5s call laser_fade_in_slow with a new random brightness
    if (millis() - last_change_time_ > 5000) {
        last_change_time_ = millis();

        const auto brightness= random(0, 255);
        if (brightness < 100) {
            laser_fade_in_slow(0);
        } else {
            laser_fade_in_slow(brightness);
        }
    }
}

Otherwise, the effect for pwn_pins[0] will run Forever, because it was initially set to do so.
Also when using the JLedSequence, once it is finished, changes to the contained Leds in pwm_pins will have no effect, since the JLedSequence is configured to just run once.

@oscgonfer
Copy link
Author

oscgonfer commented Feb 26, 2022

Okay... so say I do this for both pins:

#include <jled.h>

#define LASER_PIN       21
#define FRONTLIGHT_PIN  22
#define FADESLOW 3000

JLed pwm_pins[] = {JLed(LASER_PIN).Breathe(255).Forever(), JLed(FRONTLIGHT_PIN).Off()};

void laser_fade_in_slow(int brightness, int what) {
    if (brightness){
        Serial.print("Set to FadeOn with brightness=");
        Serial.println(brightness);
        pwm_pins[what].FadeOn(FADESLOW).MaxBrightness(brightness).Repeat(1).Reset();
    } else {
        Serial.println("Set to FadeOff");
        pwm_pins[what].FadeOff(FADESLOW).Repeat(1).Reset();
    }
}

Note that pwm_pins[0] starts with a Breathe(255).Forever(), while the other one doesn't.

Then, when I call laser_fade_in_slow(255, 1), it works perfectly (I can later on update with no issue), but with laser_fade_in_slow(255, 0) it makes the FadeOn on LASER_PIN, but afterwards I can't update it.

@jandelgado
Copy link
Owner

jandelgado commented Feb 27, 2022

I modified the example to call your laser_fade_in_slow function every 5s with random values. Works as expected, LEDs changing state continously (I am using an ESP32 for the test). Could you pleas try the example and the latest JLed Version? Which Micro controller and Framework are you using?

#include <jled.h>

#define LASER_PIN 21
#define FRONTLIGHT_PIN 22
#define FADESLOW 3000

#define LASER_PIN 21
#define FRONTLIGHT_PIN 22
#define FADESLOW 3000

JLed pwm_pins[] = {JLed(LASER_PIN).Breathe(255).Forever(),
                   JLed(FRONTLIGHT_PIN).Off()};

void laser_fade_in_slow(int brightness, int what) {
    Serial.print("For LED=");
    Serial.print(what);
    if (brightness) {
        Serial.print(", set to FadeOn with brightness=");
        Serial.println(brightness);
        pwm_pins[what]
            .FadeOn(FADESLOW)
            .MaxBrightness(brightness)
            .Repeat(1)
            .Reset();
    } else {
        Serial.println(", set to FadeOff");
        pwm_pins[what].FadeOff(FADESLOW).Repeat(1).Reset();
    }
}

void setup() {
    Serial.begin(9600);
}

void loop() {
    static unsigned long last_change_time_ = 0;

    pwm_pins[0].Update();
    pwm_pins[1].Update();

    delay(1);

    // every 5s call laser_fade_in_slow with a new random brightness
    if (millis() - last_change_time_ > 5000) {
        last_change_time_ = millis();

        const auto brightness = random(0, 255);
        const auto what = random(0, 2);
        if (brightness < 100) {
            laser_fade_in_slow(0, what);
        } else {
            laser_fade_in_slow(brightness, what);
        }
    }
}

@oscgonfer
Copy link
Author

Hi!

Sorry for not answering for a while. I didn't have the time to test this part until now.

TL;DR

  • your test code works perfectly, no issue
  • the framework I am using is Arduino, board is a RF69HCW featherm0 board. I am also using RadioHead and neopixelbus for managing radio communications and controlling RGB ledstrips respectively. The code for the project I am making is here
  • Issue is now solved, process for it is below

Step 1. Adding Repeat(1) to pwm_pins[X].FadeOn(FADESLOW).MaxBrightness(brightness); makes the animation only be triggered once, which accomplishes the "stay on forever" part.

Step 2. Adding Reset() to pwm_pins[X].FadeOn(FADESLOW).MaxBrightness(brightness).Repeat(1); doesn't seem to solve the "unable to update sequence" afterwards (see below)

Step 3. I saw in your code that you perform pwm_pins[0].Update(); and pwm_pins[1].Update(); in the loop, instead of a sequence.Update(); of a JLedSequence sequence(JLedSequence::eMode::PARALLEL, pwm_pins); that I had declared after the pwm pins (see first comment). This seems to solve the issue, and actually, seems like the JLedSequence is no longer necessary and I don't fully understand why. Eitherway, issue seems to be solved and code is updated... so many thanks for your support, your code, and your library ❤️

@jandelgado
Copy link
Owner

Regarding the JLedSequence, I think you hit the same problem as described in #90:

The JLedSequence sequence object has a state and in your setup, the sequence is in state "not running", because both JLed objects are already/initially Off. So further calls to sequence.Update() will have no effect. Try to call sequence.Reset() in your ProcessLine function.

In your case also once the sequence "is done", it will not re-start when you reset the contained LEDs. The JLedSequence object itself has to be resetted using Reset()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants